Merge pull request #12 from biveraxe/ver4dev

Слил с основой
This commit is contained in:
Mit4el
2023-07-06 21:39:51 +03:00
committed by GitHub
32 changed files with 1326 additions and 247 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,2 @@
.pio
.vscode
/myProfile_wm.json

View File

@@ -399,45 +399,7 @@
},
{
"global": 0,
"name": "27. DS2423 счетчик 1",
"type": "Reading",
"subtype": "Ds2423a",
"id": "dscounta",
"widget": "anydataDef",
"page": "Счетчики",
"descr": "DS1 V",
"plus": 0,
"multiply": 1,
"pin": 4,
"index": 0,
"addr": "",
"int": 10,
"round": 0,
"needSave": 0,
"num": 27
},
{
"global": 0,
"name": "28. DS2423 счетчик 2",
"type": "Reading",
"subtype": "Ds2423b",
"id": "dscountb",
"widget": "anydataDef",
"page": "Счетчики",
"descr": "DS2 V",
"plus": 0,
"multiply": 1,
"pin": 4,
"index": 0,
"addr": "",
"int": 10,
"round": 0,
"needSave": 0,
"num": 28
},
{
"global": 0,
"name": "29. Аналоговый счетчик импульсов",
"name": "27. Аналоговый счетчик импульсов",
"type": "Writing",
"subtype": "Impulse",
"id": "impulse",
@@ -450,32 +412,11 @@
"pinMode": "INPUT",
"debounceDelay": 3,
"multiply": 1,
"num": 29
"num": 27
},
{
"global": 0,
"name": "30. Cенсор температуры NTC",
"type": "Reading",
"subtype": "Ntc",
"id": "Ntctmp",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "NTC Температура",
"needSave": 0,
"val": "0",
"int": 15,
"pin": "35",
"R1": "10000",
"R0": "10000",
"Beta": "3950.0",
"T0": "25",
"Vs": "3.3",
"round": 1,
"num": 30
},
{
"global": 0,
"name": "31. PZEM 004t Напряжение",
"name": "28. PZEM 004t Напряжение",
"type": "Reading",
"subtype": "Pzem004v",
"id": "v",
@@ -485,11 +426,11 @@
"int": 15,
"addr": "0xF8",
"round": 1,
"num": 31
"num": 28
},
{
"global": 0,
"name": "32. PZEM 004t Сила тока",
"name": "29. PZEM 004t Сила тока",
"type": "Reading",
"subtype": "Pzem004a",
"id": "a",
@@ -499,11 +440,11 @@
"int": 15,
"addr": "0xF8",
"round": 1,
"num": 32
"num": 29
},
{
"global": 0,
"name": "33. PZEM 004t Мощность",
"name": "30. PZEM 004t Мощность",
"type": "Reading",
"subtype": "Pzem004w",
"id": "w",
@@ -513,11 +454,11 @@
"int": 15,
"addr": "0xF8",
"round": 1,
"num": 33
"num": 30
},
{
"global": 0,
"name": "34. PZEM 004t Энергия",
"name": "31. PZEM 004t Энергия",
"type": "Reading",
"subtype": "Pzem004wh",
"id": "wh",
@@ -527,11 +468,11 @@
"int": 15,
"addr": "0xF8",
"round": 1,
"num": 34
"num": 31
},
{
"global": 0,
"name": "35. PZEM 004t Частота",
"name": "32. PZEM 004t Частота",
"type": "Reading",
"subtype": "Pzem004hz",
"id": "hz",
@@ -541,11 +482,11 @@
"int": 15,
"addr": "0xF8",
"round": 1,
"num": 35
"num": 32
},
{
"global": 0,
"name": "36. PZEM 004t Косинус",
"name": "33. PZEM 004t Косинус",
"type": "Reading",
"subtype": "Pzem004pf",
"id": "pf",
@@ -555,11 +496,11 @@
"int": 15,
"addr": "0xF8",
"round": 1,
"num": 36
"num": 33
},
{
"global": 0,
"name": "37. PZEM настройка",
"name": "34. PZEM настройка",
"type": "Reading",
"subtype": "Pzem004cmd",
"id": "set",
@@ -571,11 +512,11 @@
"changeaddr": 0,
"setaddr": "0x01",
"reset": 0,
"num": 37
"num": 34
},
{
"global": 0,
"name": "38. Часы реального времени",
"name": "35. Часы реального времени",
"type": "Reading",
"subtype": "RTC",
"id": "rtc",
@@ -591,11 +532,11 @@
"int": 5,
"btn-setUTime": "0",
"btn-setSysTime": "nil",
"num": 38
"num": 35
},
{
"name": "39. (S8) Cенсор качества воздуха",
"num": 39,
"name": "36. (S8) Cенсор качества воздуха",
"num": 36,
"type": "Reading",
"subtype": "S8co",
"id": "s8co",
@@ -609,50 +550,7 @@
},
{
"global": 0,
"name": "40. SCD40 Углекислый газ",
"type": "Reading",
"subtype": "Scd40co2",
"id": "Scd40co2",
"widget": "anydataPpm",
"page": "Сенсоры",
"descr": "SCD40 Углекислый газ",
"int": 15,
"round": 0,
"lowPeriodic": 1,
"autoCalibration": 1,
"btn-Recalibration": 0,
"num": 40
},
{
"global": 0,
"name": "41. SCD40 Влажность",
"type": "Reading",
"subtype": "Scd40h",
"id": "Scd40h",
"widget": "anydataHum",
"page": "Сенсоры",
"descr": "SCD40 Влажность",
"int": 15,
"round": 1,
"num": 41
},
{
"global": 0,
"name": "42. SCD40 Температура",
"type": "Reading",
"subtype": "Scd40t",
"id": "Scd40t",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "SCD40 Температура",
"int": 15,
"round": 1,
"offset": 4,
"num": 42
},
{
"global": 0,
"name": "43. Sht20 Температура",
"name": "37. Sht20 Температура",
"type": "Reading",
"subtype": "Sht20t",
"id": "tmp2",
@@ -661,11 +559,11 @@
"descr": "Температура",
"int": 15,
"round": 1,
"num": 43
"num": 37
},
{
"global": 0,
"name": "44. Sht20 Влажность",
"name": "38. Sht20 Влажность",
"type": "Reading",
"subtype": "Sht20h",
"id": "Hum2",
@@ -674,11 +572,11 @@
"descr": "Влажность",
"int": 15,
"round": 1,
"num": 44
"num": 38
},
{
"global": 0,
"name": "45. Sht30 Температура",
"name": "39. Sht30 Температура",
"type": "Reading",
"subtype": "Sht30t",
"id": "tmp30",
@@ -687,11 +585,11 @@
"descr": "SHT30 Температура",
"int": 15,
"round": 1,
"num": 45
"num": 39
},
{
"global": 0,
"name": "46. Sht30 Влажность",
"name": "40. Sht30 Влажность",
"type": "Reading",
"subtype": "Sht30h",
"id": "Hum30",
@@ -700,12 +598,12 @@
"descr": "SHT30 Влажность",
"int": 15,
"round": 1,
"num": 46
"num": 40
},
{
"global": 0,
"name": "47. HC-SR04 Ультразвуковой дальномер",
"num": 47,
"name": "41. HC-SR04 Ультразвуковой дальномер",
"num": 41,
"type": "Reading",
"subtype": "Sonar",
"id": "sonar",
@@ -717,7 +615,7 @@
"int": 5
},
{
"name": "48. UART",
"name": "42. UART",
"type": "Reading",
"subtype": "UART",
"page": "",
@@ -729,14 +627,14 @@
"line": 2,
"speed": 9600,
"eventFormat": 0,
"num": 48
"num": 42
},
{
"header": "Исполнительные устройства"
},
{
"global": 0,
"name": "49. Кнопка подключенная к пину",
"name": "43. Кнопка подключенная к пину",
"type": "Writing",
"subtype": "ButtonIn",
"id": "btn",
@@ -751,11 +649,11 @@
"debounceDelay": 50,
"fixState": 0,
"inv": 0,
"num": 49
"num": 43
},
{
"global": 0,
"name": "50. Управление пином",
"name": "44. Управление пином",
"type": "Writing",
"subtype": "ButtonOut",
"needSave": 0,
@@ -766,11 +664,11 @@
"int": 0,
"inv": 0,
"pin": 2,
"num": 50
"num": 44
},
{
"global": 0,
"name": "51. Пассивный звуковой извещатель",
"name": "45. Пассивный звуковой извещатель",
"type": "Writing",
"subtype": "Buzzer",
"id": "buzzer",
@@ -789,11 +687,11 @@
"cycle": 0,
"indication": 1,
"val": 0,
"num": 51
"num": 45
},
{
"global": 0,
"name": "52. Энкодер",
"name": "46. Энкодер",
"type": "Writing",
"subtype": "Encoder",
"id": "enc",
@@ -806,11 +704,11 @@
"step": 1,
"stepOnPress": 5,
"pins": "4,5,2",
"num": 52
"num": 46
},
{
"global": 0,
"name": "53. Сервопривод",
"name": "47. Сервопривод",
"type": "Writing",
"subtype": "IoTServo",
"id": "servo",
@@ -821,11 +719,11 @@
"pin": 12,
"apin": -1,
"amap": "0, 4096, 0, 180",
"num": 53
"num": 47
},
{
"global": 0,
"name": "54. Расширитель портов Mcp23017",
"name": "48. Расширитель портов Mcp23017",
"type": "Reading",
"subtype": "Mcp23017",
"id": "Mcp",
@@ -835,11 +733,11 @@
"int": "0",
"addr": "0x20",
"index": 1,
"num": 54
"num": 48
},
{
"global": 0,
"name": "55. MP3 плеер",
"name": "49. MP3 плеер",
"type": "Reading",
"subtype": "Mp3",
"id": "mp3",
@@ -849,11 +747,11 @@
"int": 1,
"pins": "14,12",
"volume": 20,
"num": 55
"num": 49
},
{
"global": 0,
"name": "56. Сенсорная кнопка",
"name": "50. Сенсорная кнопка",
"type": "Writing",
"subtype": "Multitouch",
"id": "impulse",
@@ -867,11 +765,11 @@
"pinMode": "INPUT",
"debounceDelay": 50,
"PWMDelay": 500,
"num": 56
"num": 50
},
{
"global": 0,
"name": "57. Расширитель портов Pcf8574",
"name": "51. Расширитель портов Pcf8574",
"type": "Reading",
"subtype": "Pcf8574",
"id": "Pcf",
@@ -881,11 +779,11 @@
"int": "0",
"addr": "0x20",
"index": 1,
"num": 57
"num": 51
},
{
"global": 0,
"name": "58. PWM ESP8266",
"name": "52. PWM ESP8266",
"type": "Writing",
"subtype": "Pwm8266",
"id": "pwm",
@@ -897,11 +795,11 @@
"freq": 5000,
"val": 0,
"apin": -1,
"num": 58
"num": 52
},
{
"global": 0,
"name": "59. Телеграм-Лайт",
"name": "53. Телеграм-Лайт",
"type": "Writing",
"subtype": "TelegramLT",
"id": "tg",
@@ -910,14 +808,14 @@
"descr": "",
"token": "",
"chatID": "",
"num": 59
"num": 53
},
{
"header": "Экраны"
},
{
"global": 0,
"name": "60. LCD экран 2004",
"name": "54. LCD экран 2004",
"type": "Reading",
"subtype": "Lcd2004",
"id": "Lcd",
@@ -929,10 +827,10 @@
"size": "20,4",
"coord": "0,0",
"id2show": "id датчика",
"num": 60
"num": 54
},
{
"name": "61. LCD экран 1602",
"name": "55. LCD экран 1602",
"type": "Reading",
"subtype": "Lcd2004",
"id": "Lcd",
@@ -944,6 +842,6 @@
"size": "16,2",
"coord": "0,0",
"id2show": "id датчика",
"num": 61
"num": 55
}
]

View File

@@ -118,7 +118,7 @@
},
{
"path": "src/modules/sensors/Ds2423",
"active": true
"active": false
},
{
"path": "src/modules/sensors/Emon",
@@ -160,6 +160,10 @@
"path": "src/modules/sensors/IoTWiegand",
"active": false
},
{
"path": "src/modules/sensors/ld2410",
"active": false
},
{
"path": "src/modules/sensors/Max6675",
"active": false
@@ -170,7 +174,7 @@
},
{
"path": "src/modules/sensors/Ntc",
"active": true
"active": false
},
{
"path": "src/modules/sensors/Pzem004t",
@@ -190,7 +194,7 @@
},
{
"path": "src/modules/sensors/Scd40",
"active": true
"active": false
},
{
"path": "src/modules/sensors/Sds011",
@@ -238,6 +242,10 @@
"path": "src/modules/exec/EspCam",
"active": false
},
{
"path": "src/modules/exec/Ftp",
"active": false
},
{
"path": "src/modules/exec/HttpGet",
"active": false
@@ -312,6 +320,10 @@
"path": "src/modules/display/NextionUpload",
"active": false
},
{
"path": "src/modules/display/Smi2_m",
"active": true
},
{
"path": "src/modules/display/Ws2812b",
"active": false

View File

@@ -8,14 +8,14 @@
<link rel="icon" type="image/png" href="/favicon.ico" />
<link
rel="stylesheet"
href="https://iotmanager.org/esp01ota/build/bundle.css?443"
href="https://iotmanager.org/esp01ota/build/bundle.css?450"
/>
</head>
<body>
<script>
let script = document.createElement("script");
script.src = "https://iotmanager.org/esp01ota/build/bundle.js?443";
script.src = "https://iotmanager.org/esp01ota/build/bundle.js?450";
script.onload = execute;
document.head.append(script);
script.onerror = error;

View File

@@ -32,9 +32,17 @@
#define FIRMWARE_NAME "esp32s2_4mb"
#endif
//Размер буфера json
#define JSON_BUFFER_SIZE 2048 // держим 2 кб не меняем
#define WEB_SOCKETS_FRAME_SIZE 2048
// Размер буфера json
#define JSON_BUFFER_SIZE 4096 // держим 2 кб не меняем
/*
WEB_SOCKETS_FRAME_SIZE создан для того что бы не загружать оперативку.
Эта технология передаёт в сокеты большие файлы по частям.
Чем меньше этот фрейм тем теоретически лучше.
Но и сильно малый он тоже быть не должен.
Я опытным путём установил что размер 1024 является оптимальным. Можно так же поставить 2048
*/
#define WEB_SOCKETS_FRAME_SIZE 1024
// #define LOOP_DEBUG

View File

@@ -87,6 +87,7 @@ class IoTItem {
int _map3 = 0;
int _map4 = 0;
int _round = 1; // 1, 10, 100, 1000, 10000
int _numDigits = 1; // количество целых значений, не значимые позиции заменяются нулем в строковом формате
bool _global = false; // характеристика айтема, что ему нужно слать и принимать события из внешнего мира
};

View File

@@ -18,6 +18,7 @@ extern bool jsonRead(const String& json, String key, int& value, bool e = true);
extern String jsonReadStr(const String& json, String name, bool e = true);
extern int jsonReadInt(const String& json, String name, bool e = true);
long int jsonReadLInt(const String& json, String name, bool e=true);
extern boolean jsonReadBool(const String& json, String name, bool e = true);
extern bool jsonWriteStr_(String& json, const String& name, const String& value, bool e = true);

View File

@@ -45,3 +45,7 @@ String uint64ToString(uint64_t input, uint8_t base = 10);
void cleanString(String& str);
unsigned char ChartoHex(char ch);
std::vector<String> splitStr(const String& str, const String& delimiter);
bool strInVector(const String& str, const std::vector<String>& vec);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -160,6 +160,10 @@
"path": "src/modules/sensors/IoTWiegand",
"active": false
},
{
"path": "src/modules/sensors/ld2410",
"active": false
},
{
"path": "src/modules/sensors/Max6675",
"active": false
@@ -316,6 +320,10 @@
"path": "src/modules/display/NextionUpload",
"active": false
},
{
"path": "src/modules/display/Smi2_m",
"active": true
},
{
"path": "src/modules/display/Ws2812b",
"active": false

View File

@@ -248,11 +248,11 @@ lib_deps =
adafruit/Adafruit BME280 Library
adafruit/Adafruit BMP280 Library
https://github.com/milesburton/Arduino-Temperature-Control-Library
IRremote @ ^4.1.2
https://github.com/tremaru/iarduino_RTC
robtillaart/SHT2x@^0.1.1
WEMOS SHT3x@1.0.0
plerup/EspSoftwareSerial
gyverlibs/EncButton @ ^2.0
adafruit/Adafruit MCP23017 Arduino Library@^2.1.0
adafruit/Adafruit BusIO @ ^1.13.2
adafruit/Adafruit BusIO @ ^1.13.2
@@ -273,7 +273,7 @@ build_src_filter =
+<modules/sensors/Bmp280>
+<modules/sensors/Ds18b20>
+<modules/sensors/Impulse>
+<modules/sensors/IRswitch>
+<modules/sensors/Ntc>
+<modules/sensors/Pzem004t>
+<modules/sensors/RTC>
+<modules/sensors/Sht20>
@@ -282,6 +282,8 @@ build_src_filter =
+<modules/sensors/UART>
+<modules/exec/ButtonIn>
+<modules/exec/ButtonOut>
+<modules/exec/Buzzer>
+<modules/exec/Enconder>
+<modules/exec/Mcp23017>
+<modules/exec/Multitouch>
+<modules/exec/Pcf8574>
@@ -374,6 +376,7 @@ build_src_filter =
+<modules/sensors/Bmp280>
+<modules/sensors/Ds18b20>
+<modules/sensors/Impulse>
+<modules/sensors/Ntc>
+<modules/sensors/Pzem004t>
+<modules/sensors/RTC>
+<modules/sensors/Sht20>
@@ -382,6 +385,7 @@ build_src_filter =
+<modules/sensors/UART>
+<modules/exec/ButtonIn>
+<modules/exec/ButtonOut>
+<modules/exec/Buzzer>
+<modules/exec/Enconder>
+<modules/exec/Mcp23017>
+<modules/exec/Multitouch>
@@ -397,11 +401,7 @@ lib_deps =
adafruit/Adafruit BMP280 Library
beegee-tokyo/DHT sensor library for ESPx
https://github.com/milesburton/Arduino-Temperature-Control-Library
https://github.com/jbechter/arduino-onewire-DS2423
paulstoffregen/OneWire @ ^2.3.7
https://github.com/tremaru/iarduino_RTC
Sensirion I2C SCD4x @0.4.0
Sensirion Core @0.6.0
robtillaart/SHT2x@^0.1.1
WEMOS SHT3x@1.0.0
plerup/EspSoftwareSerial
@@ -428,13 +428,10 @@ build_src_filter =
+<modules/sensors/Bmp280>
+<modules/sensors/Dht1122>
+<modules/sensors/Ds18b20>
+<modules/sensors/Ds2423>
+<modules/sensors/Impulse>
+<modules/sensors/Ntc>
+<modules/sensors/Pzem004t>
+<modules/sensors/RTC>
+<modules/sensors/S8>
+<modules/sensors/Scd40>
+<modules/sensors/Sht20>
+<modules/sensors/Sht30>
+<modules/sensors/Sonar>
@@ -454,29 +451,43 @@ build_src_filter =
[env:esp32_4mb_fromitems]
lib_deps =
https://github.com/enjoyneering/AHTxx.git
adafruit/Adafruit BME280 Library
adafruit/Adafruit BMP280 Library
beegee-tokyo/DHT sensor library for ESPx
https://github.com/milesburton/Arduino-Temperature-Control-Library
https://github.com/jbechter/arduino-onewire-DS2423
paulstoffregen/OneWire @ ^2.3.7
https://github.com/tremaru/iarduino_RTC
robtillaart/SHT2x@^0.1.1
WEMOS SHT3x@1.0.0
plerup/EspSoftwareSerial
gyverlibs/EncButton @ ^2.0
https://github.com/RoboticsBrno/ServoESP32
adafruit/Adafruit MCP23017 Arduino Library@^2.1.0
adafruit/Adafruit BusIO @ ^1.13.2
dfrobot/DFRobotDFPlayerMini @ ^1.0.5
adafruit/Adafruit BusIO @ ^1.13.2
https://github.com/robotclass/RobotClass_LiquidCrystal_I2C
marcoschwartz/LiquidCrystal_I2C@^1.1.4
build_src_filter =
+<modules/virtual/Cron>
+<modules/virtual/GoogleSheet>
+<modules/virtual/Loging>
+<modules/virtual/LogingDaily>
+<modules/virtual/Timer>
+<modules/virtual/Variable>
+<modules/virtual/VariableColor>
+<modules/virtual/VButton>
+<modules/sensors/Acs712>
+<modules/sensors/AhtXX>
+<modules/sensors/AnalogAdc>
+<modules/sensors/Bme280>
+<modules/sensors/Bmp280>
+<modules/sensors/Dht1122>
+<modules/sensors/Ds18b20>
+<modules/sensors/Ds2423>
+<modules/sensors/Impulse>
+<modules/sensors/Ntc>
+<modules/sensors/Pzem004t>
+<modules/sensors/RTC>
+<modules/sensors/S8>
+<modules/sensors/Sht20>
+<modules/sensors/Sht30>
+<modules/sensors/Sonar>
+<modules/sensors/UART>
@@ -484,9 +495,15 @@ build_src_filter =
+<modules/exec/ButtonOut>
+<modules/exec/Buzzer>
+<modules/exec/Enconder>
+<modules/exec/IoTServo>
+<modules/exec/Mcp23017>
+<modules/exec/Mp3>
+<modules/exec/Multitouch>
+<modules/exec/Pcf8574>
+<modules/exec/Pwm32>
+<modules/exec/TelegramLT>
+<modules/display/Lcd2004>
+<modules/display/Smi2_m>
[env:esp32s2_4mb_fromitems]
lib_deps =

View File

@@ -3,7 +3,7 @@
#include "classes/IoTDB.h"
#include "utils/Statistic.h"
#include <Wire.h>
#ifdef esp32s2_4mb
#ifdef esp32s2_4mb
#include <USB.h>
#endif
@@ -80,9 +80,9 @@ void stopErrorMarker(int id) {
}
void setup() {
#ifdef esp32s2_4mb
#ifdef esp32s2_4mb
USB.begin();
#endif
#endif
#ifdef esp32_4mb
My_timer = timerBegin(0, 80, true);
timerAttachInterrupt(My_timer, &onTimer, true);
@@ -107,7 +107,7 @@ void setup() {
Serial.println("FIRMWARE NAME " + String(FIRMWARE_NAME));
Serial.println("FIRMWARE VERSION " + String(FIRMWARE_VERSION));
Serial.println("WEB VERSION " + getWebVersion());
const String buildTime = String(BUILD_DAY) + "/" + String(BUILD_MONTH) + "/" + String(BUILD_YEAR) + " " + String(BUILD_HOUR) + ":" + String(BUILD_MIN) + ":" + String(BUILD_SEC);
const String buildTime = String(BUILD_DAY) + "." + String(BUILD_MONTH) + "." + String(BUILD_YEAR) + " " + String(BUILD_HOUR) + ":" + String(BUILD_MIN) + ":" + String(BUILD_SEC);
Serial.println("BUILD TIME " + buildTime);
jsonWriteStr_(errorsHeapJson, F("bt"), buildTime);
Serial.println(F("------------------------"));

View File

@@ -15,6 +15,7 @@ IoTItem::IoTItem(const String& parameters) {
if (!jsonRead(parameters, F("multiply"), _multiply, false)) _multiply = 1;
if (!jsonRead(parameters, F("plus"), _plus, false)) _plus = 0;
if (!jsonRead(parameters, F("round"), _round, false)) _round = -1;
if (!jsonRead(parameters, F("numDigits"), _numDigits, false)) _numDigits = 1;
if (!jsonRead(parameters, F("global"), _global, false)) _global = false;
@@ -119,9 +120,9 @@ String IoTItem::getRoundValue() {
if (_round >= 0 && _round <= 6) {
int sot = _round ? pow(10, (int)_round) : 1;
value.valD = round(value.valD * sot) / sot;
//todo: оптимизировать. Вынести расчет строки формата округления, чтоб использовать постоянно готовую
char buf[15];
sprintf(buf, ("%1." + (String)_round + "f").c_str(), value.valD);
sprintf(buf, ("%0" + (String)(_numDigits + _round) + "." + (String)_round + "f").c_str(), value.valD);
value.valS = (String)buf;
return value.valS;
} else {

View File

@@ -15,13 +15,10 @@ void* getAPI_Bme280(String subtype, String params);
void* getAPI_Bmp280(String subtype, String params);
void* getAPI_Dht1122(String subtype, String params);
void* getAPI_Ds18b20(String subtype, String params);
void* getAPI_Ds2423(String subtype, String params);
void* getAPI_Impulse(String subtype, String params);
void* getAPI_Ntc(String subtype, String params);
void* getAPI_Pzem004(String subtype, String params);
void* getAPI_RTC(String subtype, String params);
void* getAPI_S8(String subtype, String params);
void* getAPI_Scd40(String subtype, String params);
void* getAPI_Sht20(String subtype, String params);
void* getAPI_Sht30(String subtype, String params);
void* getAPI_Sonar(String subtype, String params);
@@ -56,13 +53,10 @@ if ((tmpAPI = getAPI_Bme280(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Bmp280(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Dht1122(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Ds18b20(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Ds2423(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Impulse(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Ntc(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Pzem004(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_RTC(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_S8(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Scd40(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Sht20(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Sht30(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Sonar(subtype, params)) != nullptr) return tmpAPI;

View File

@@ -1,22 +1,14 @@
#include "Global.h"
#include "classes/IoTItem.h"
//#include "LiquidCrystal_I2C.h"
#include <RobotClass_LiquidCrystal_I2C.h>
#include <map>
void scanI2C();
//LiquidCrystal_I2C *LCDI2C;
RobotClass_LiquidCrystal_I2C *LCDI2C;
class Lcd2004 : public IoTItem {
private:
unsigned int _x;
unsigned int _y;
String _id2show;
String _descr;
String _id2show, _prefix = "", _postfix = "";
int _prevStrSize;
String _addr;
@@ -37,42 +29,52 @@ class Lcd2004 : public IoTItem {
int w = selectFromMarkerToMarker(size, ",", 0).toInt(); //количество столбцов
int h = selectFromMarkerToMarker(size, ",", 1).toInt(); //количество строк
if (LCDI2C == nullptr) { //инициализации экрана еще не было
//LCDI2C = new LiquidCrystal_I2C(hexStringToUint8(_addr), w, h);
LCDI2C = new RobotClass_LiquidCrystal_I2C(hexStringToUint8(_addr), w, h, CP_UTF8);
if (LCDI2C != nullptr) {
LCDI2C->init();
LCDI2C->clear();
LCDI2C->backlight();
}
}
LCDI2C->clear();
LCDI2C->backlight();
jsonRead(parameters, "coord", xy);
_x = selectFromMarkerToMarker(xy, ",", 0).toInt();
_y = selectFromMarkerToMarker(xy, ",", 1).toInt();
jsonRead(parameters, "descr", _descr);
jsonRead(parameters, "id2show", _id2show);
jsonRead(parameters, "prefix", _prefix);
jsonRead(parameters, "postfix", _postfix);
}
void doByInterval() {
if (LCDI2C != nullptr) {
printBlankStr(_prevStrSize);
String tmpStr = getItemValue(_id2show);
if (_descr != "none") tmpStr = _descr + " " + tmpStr;
LCDI2C->setCursor(_x, _y);
LCDI2C->print(tmpStr);
//LCDI2C->print("Helloy,Manager 404 !");
//Serial.printf("ffff %s\n", _id2show);
_prevStrSize = tmpStr.length();
} else {
scanI2C();
void drawItem(IoTItem* item) {
String tmpStr = _prefix;
tmpStr += item->getValue();
tmpStr += _postfix;
printBlankStr(_prevStrSize);
LCDI2C->setCursor(_x, _y);
LCDI2C->print(tmpStr);
_prevStrSize = tmpStr.length();
}
void setValue(const IoTValue& Value, bool genEvent = true) {
if (LCDI2C == nullptr) return;
value = Value;
drawItem(this);
IoTItem::setValue(Value, genEvent);
}
void onRegEvent(IoTItem* eventItem) {
if (LCDI2C == nullptr) { scanI2C(); return;}
if (!eventItem || _id2show == "") return;
if (_id2show == eventItem->getID()) {
setValue(eventItem->value, false);
}
}
IoTValue execute(String command, std::vector<IoTValue> &param) { // будет возможным использовать, когда сценарии запустятся
IoTValue execute(String command, std::vector<IoTValue> &param) {
if (command == "noBacklight")
LCDI2C->noBacklight();
else if (command == "backlight")
@@ -99,9 +101,13 @@ class Lcd2004 : public IoTItem {
if (param.size()) {
_y = param[0].valD;
}
} else if (command == "descr") {
} else if (command == "prefix") {
if (param.size()) {
_descr = param[0].valS;
_prefix = param[0].valS;
}
} else if (command == "postfix") {
if (param.size()) {
_postfix = param[0].valS;
}
} else if (command == "id2show") {
if (param.size()) {

View File

@@ -7,30 +7,32 @@
"type": "Reading",
"subtype": "Lcd2004",
"id": "Lcd",
"widget": "",
"page": "",
"descr": "T",
"widget": "inputTxt",
"page": "Экраны",
"descr": "LCD Экран",
"int": 15,
"addr": "0x27",
"size": "20,4",
"coord": "0,0",
"id2show": "id датчика"
"id2show": "",
"prefix": "",
"postfix": ""
},
{
"name": "LCD экран 1602",
"type": "Reading",
"subtype": "Lcd2004",
"id": "Lcd",
"widget": "",
"page": "",
"descr": "T",
"widget": "inputTxt",
"page": "Экраны",
"descr": "LCD Экран",
"int": 15,
"addr": "0x27",
"size": "16,2",
"coord": "0,0",
"id2show": "id датчика"
"id2show": "",
"prefix": "",
"postfix": ""
}],
"about": {
@@ -46,11 +48,12 @@
},
"moduleDesc": "Позволяет выводить на символьные экраны по указанным позициям значения других элементов конфигурации.",
"propInfo": {
"int": "Период времени в секундах обновления информации на экране по конкретному элементу.",
"addr": "Адрес устройства на шине, обычно 0x27.",
"addr": "Адрес устройства на шине, обычно 0x27. Установите пустую строку для включения режима сканирования адресов на шине (результат в консоли).",
"size": "Размерность матрицы экрана.",
"coord": "Координата позиции для вывода данных элемента конфигурации.",
"id2show": "id элемента конфигурации."
"id2show": "id элемента конфигурации для отображения на экране. Если пустое значение, то данные берутся из собственной переменной.",
"prefix": "Символы до значения.",
"postfix": "Символы после значения."
},
"funcInfo": [
{
@@ -89,10 +92,15 @@
"params": ["Номер столбца первого символа"]
},
{
"name": "descr",
"name": "prefix",
"descr": "Задает приставку слева от значения",
"params": ["Строка"]
},
{
"name": "postfix",
"descr": "Задает приставку справа от значения",
"params": ["Строка"]
},
{
"name": "id2show",
"descr": "Задает ИД элемента, значение которого хотим отображать на экране",

View File

@@ -0,0 +1,150 @@
#include "Modbus_master_for_Smi2_m.h"
Smi_display::Smi_display() {
}
// Modbus Master
void Smi_display::modbus_update() {
idle();
}
void Smi_display::idle() {
static unsigned int packet_index;
unsigned int failed_connections = 0;
unsigned char current_connection;
do {
if (packet_index == total_no_of_packets) // wrap around to the beginning
packet_index = 0;
// proceed to the next packet
packet = &packetArray[packet_index];
// get the current connection status
current_connection = packet->connection;
if (!current_connection) {
// If all the connection attributes are false return
// immediately to the main sketch
if (++failed_connections == total_no_of_packets)
return;
}
packet_index++;
// if a packet has no connection get the next one
} while (!current_connection);
constructPacket();
}
void Smi_display::constructPacket() {
packet->requests++;
frame[0] = packet->id;
frame[1] = packet->function;
frame[2] = packet->address >> 8; // address Hi
frame[3] = packet->address & 0xFF; // address Lo
frame[4] = packet->data >> 8; // MSB
frame[5] = packet->data & 0xFF; // LSB
unsigned char frameSize;
// construct the frame according to the modbus function
if (packet->function == PRESET_MULTIPLE_REGISTERS)
frameSize = construct_F16();
else // else functions 1,2,3,4,5 & 6 is assumed. They all share the exact same request format.
frameSize = 8; // the request is always 8 bytes in size for the above mentioned functions.
unsigned int crc16 = calculateCRC(frameSize - 2);
frame[frameSize - 2] = crc16 >> 8; // split crc into 2 bytes
frame[frameSize - 1] = crc16 & 0xFF;
sendPacket(frameSize);
}
unsigned char Smi_display::construct_F16() {
unsigned char no_of_bytes = packet->data * 2;
// first 6 bytes of the array + no_of_bytes + 2 bytes CRC
frame[6] = no_of_bytes; // number of bytes
unsigned char index = 7; // user data starts at index 7
unsigned char no_of_registers = packet->data;
/*unsigned*/ int temp;
for (unsigned char i = 0; i < no_of_registers; i++) {
temp = register_array[packet->local_start_address + i]; // get the data
frame[index] = temp >> 8;
index++;
frame[index] = temp & 0xFF;
index++;
}
unsigned char frameSize = (9 + no_of_bytes); // first 7 bytes of the array + 2 bytes CRC + noOfBytes
return frameSize;
}
void Smi_display::modbus_configure(HardwareSerial* SerialPort,
long baud,
unsigned char byteFormat,
int rx,
int tx,
unsigned int _TxEnablePin,
Packet* _packets,
unsigned int _total_no_of_packets,
/*unsigned*/ int* _register_array) {
TxEnablePin = _TxEnablePin;
total_no_of_packets = _total_no_of_packets;
packetArray = _packets;
register_array = _register_array;
ModbusPort = SerialPort;
(*ModbusPort).begin(baud, byteFormat, rx, tx);
pinMode(TxEnablePin, OUTPUT);
digitalWrite(TxEnablePin, LOW);
}
void Smi_display::modbus_construct(Packet* _packet,
unsigned char id,
unsigned char function,
unsigned int address,
unsigned int data,
unsigned int local_start_address) {
_packet->id = id;
_packet->function = function;
_packet->address = address;
_packet->data = data;
_packet->local_start_address = local_start_address;
_packet->connection = 1;
}
unsigned int Smi_display::calculateCRC(unsigned char bufferSize) {
unsigned int temp, temp2, flag;
temp = 0xFFFF;
for (unsigned char i = 0; i < bufferSize; i++) {
temp = temp ^ frame[i];
for (unsigned char j = 1; j <= 8; j++) {
flag = temp & 0x0001;
temp >>= 1;
if (flag)
temp ^= 0xA001;
}
}
// Reverse byte order.
temp2 = temp >> 8;
temp = (temp << 8) | temp2;
temp &= 0xFFFF;
// the returned value is already swapped
// crcLo byte is first & crcHi byte is last
return temp;
}
void Smi_display::sendPacket(unsigned char bufferSize) {
digitalWrite(TxEnablePin, HIGH);
for (unsigned char i = 0; i < bufferSize; i++)
(*ModbusPort).write(frame[i]);
(*ModbusPort).flush();
digitalWrite(TxEnablePin, LOW);
}

View File

@@ -0,0 +1,71 @@
#pragma once
#include "HardwareSerial.h"
#define PRESET_MULTIPLE_REGISTERS 16
#define BUFFER_SIZE 64
typedef struct
{
unsigned char id;
unsigned char function;
unsigned int address;
unsigned int data;
unsigned int local_start_address;
unsigned int requests;
unsigned int successful_requests;
unsigned int failed_requests;
unsigned int exception_errors;
unsigned int retries;
unsigned char connection;
} Packet;
class Smi_display {
public:
Smi_display();
~Smi_display();
public:
void modbus_update();
void modbus_construct(Packet* _packet,
unsigned char id,
unsigned char function,
unsigned int address,
unsigned int data,
unsigned _local_start_address);
void modbus_configure(HardwareSerial* SerialPort,
long baud,
unsigned char byteFormat,
int rx,
int tx,
unsigned int _TxEnablePin,
Packet* _packets,
unsigned int _total_no_of_packets,
/*unsigned*/ int* _register_array);
private:
void idle();
void constructPacket();
unsigned char construct_F16();
unsigned int calculateCRC(unsigned char bufferSize);
void sendPacket(unsigned char bufferSize);
private:
unsigned char state;
unsigned char retry_count;
unsigned int TxEnablePin;
unsigned char frame[BUFFER_SIZE];
unsigned char buffer;
unsigned int T1_5;
unsigned int frameDelay;
unsigned int total_no_of_packets;
Packet* packetArray;
Packet* packet;
/*unsigned*/ int* register_array;
HardwareSerial* ModbusPort;
};

View File

@@ -0,0 +1,71 @@
#include "Global.h"
#include "classes/IoTItem.h"
#include "Modbus_master_for_Smi2_m.h"
// Общая сумма доступной памяти на ведущем устройстве, чтобы хранить данные
#define TOTAL_NO_OF_REGISTERS 4
// This is the easiest way to create new packets
// Add as many as you want. TOTAL_NO_OF_PACKETS
// is automatically updated.
enum {
PACKET1,
TOTAL_NO_OF_PACKETS // leave this last entry
};
// Масив пакетов модбус
Packet packets[TOTAL_NO_OF_PACKETS];
// Массив хранения содержимого принятых и передающихся регистров
/*unsigned*/ int regs[TOTAL_NO_OF_REGISTERS];
class Smi2_m : public IoTItem {
private:
Smi_display* smi;
unsigned int _pin; // номер порта, управляющий передачей по RS-485
long int _baud; // скорость обмена, бит/с
int _rx, _tx; // номера ножек мк, к которым подключен UART
String _show;
int i = 10;
public:
public:
Smi2_m(String parameters) : IoTItem(parameters) {
smi = new Smi_display();
_pin = jsonReadInt(parameters, "pin");
_baud = jsonReadLInt(parameters, "baud");
_rx = jsonReadInt(parameters, "rx");
_tx = jsonReadInt(parameters, "tx");
// Настраиваем пакеты
// Шестой параметр - это индекс ячейки в массиве, размещенном в памяти ведущего устройства, в которую будет
// помещен результат или из которой будут браться данные для передачи в подчиненное устройство. В нашем коде - это массив reg
// Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
// Пакет,SLAVE адрес,функция модбус,адрес регистра,данные,локальный адрес регистра.
smi->modbus_construct(&packets[PACKET1], 1, PRESET_MULTIPLE_REGISTERS, 4200, 1, 0);
smi->modbus_configure(&Serial, _baud, SERIAL_8N1, _rx, _tx, _pin, packets, TOTAL_NO_OF_PACKETS, regs);
jsonRead(parameters, "id2show", _show);
}
void doByInterval() {
if (smi) {
smi->modbus_update();
float tmpStr = getItemValue(_show).toFloat();
regs[0] = tmpStr * 10;
}
}
~Smi2_m(){};
};
void* getAPI_Smi2_m(String subtype, String param) {
if (subtype == F("Smi2_m")) {
return new Smi2_m(param);
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,56 @@
{
"menuSection": "Экраны",
"configItem": [
{
"global": 0,
"name": "Smi2_m",
"type": "Writing",
"subtype": "Smi2_m",
"id": "Smi",
"widget": "",
"page": "Дисплеи",
"descr": "",
"int": 2,
"pin": 4,
"id2show": "id датчика",
"baud": "9600",
"rx": "16",
"tx": "17"
}
],
"about": {
"moduleName": "Smi2_m",
"moduleVersion": "1.0",
"usedRam": {
"esp32_4mb": 15,
"esp8266_4mb": 15
},
"moduleDesc": "Позволяет вывести индикацию на семисегментный индикатор по Modbus (Работает в Slave режиме, Read Holding Registers 0х03)",
"propInfo": {
"int": "Период времени в секундах обновления информации на экране по конкретному элементу.",
"pin": "номер порта, управляющий передачей по RS-485",
"id2show": "id элемента конфигурации.",
"baud": "скорость обмена, бит/с"
},
"funcInfo": [
{
"name": "descr",
"descr": "Задает приставку слева от значения",
"params": [
"Строка"
]
},
{
"name": "id2show",
"descr": "Задает ИД элемента, значение которого хотим отображать на экране",
"params": [
"Имя элемента конфигурации"
]
}
]
},
"defActive": true,
"usedLibs": {
"esp32_4mb": []
}
}

View File

@@ -0,0 +1,86 @@
#include "Global.h"
#include "classes/IoTItem.h"
#include <TM1637.h>
#include <TM1638.h>
#include <TM16xxDisplay.h>
class TM16XX : public IoTItem {
private:
TM16xxDisplay *_display = nullptr;
TM16xx *_module = nullptr;
std::vector<String> _ids2show;
public:
TM16XX(String parameters) : IoTItem(parameters) {
//jsonRead(parameters, "id2show", _id2show);
int DIO, CLK, STB, chip, numDigits, intensity;
bool onoff;
String id2show;
jsonRead(parameters, "DIO", DIO);
jsonRead(parameters, "CLK", CLK);
jsonRead(parameters, "STB", STB);
jsonRead(parameters, "chip", chip);
jsonRead(parameters, "numDigits", numDigits);
jsonRead(parameters, "intensity", intensity);
jsonRead(parameters, "on", onoff);
jsonRead(parameters, "id2show", id2show);
if (id2show != "") _ids2show = splitStr(id2show, ",");
if (chip == 1637) {
_module = new TM1637(DIO, CLK, numDigits);
} else if (chip == 1638) {
_module = new TM1638(DIO, CLK, STB, numDigits);
}
_module->setupDisplay(onoff, intensity);
_display = new TM16xxDisplay(_module, numDigits);
}
void doByInterval() {
}
void setValue(const IoTValue& Value, bool genEvent = true) {
if (_display == nullptr) return;
value = Value;
_display->println(getValue());
IoTItem::setValue(Value, genEvent);
}
void onRegEvent(IoTItem* eventItem) {
if (_display == nullptr) return;
if (!eventItem || _ids2show.size() == 0) return;
if (strInVector(eventItem->getID(), _ids2show)) {
if (_ids2show.size() == 1) {
_display->println(eventItem->getValue());
} else {
_display->println();
for (int i = 0; i < _ids2show.size(); i++) {
IoTItem* item = findIoTItem(_ids2show[i]);
if (item) {
_display->print(item->getValue());
}
}
}
}
}
~TM16XX() {
delete _display;
delete _module;
};
};
void *getAPI_TM16XX(String subtype, String param) {
if (subtype == F("TM16XX")) {
return new TM16XX(param);
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,133 @@
{
"menuSection": "Экраны",
"configItem": [{
"global": 0,
"name": "7 сегментный дисплей TM16XX",
"type": "Writing",
"subtype": "TM16XX",
"id": "tm",
"widget": "inputTxt",
"page": "Экраны",
"descr": "Экран",
"round": 0,
"chip": 1637,
"numDigits": 4,
"DIO": "13",
"CLK": "14",
"STB": "12",
"intensity": "5",
"on": "1",
"id2show": ""
}],
"about": {
"authorName": "Ilya Belyakov",
"authorContact": "https://t.me/Biveraxe",
"authorGit": "https://github.com/biveraxe",
"specialThanks": "",
"moduleName": "TM16XX",
"moduleVersion": "1.0",
"usedRam": {
"esp32_4mb": 15,
"esp8266_4mb": 15
},
"moduleDesc": "Позволяет выводить на 7 сегментный экран серии TM16XX (TM1637, TM1638). Может быть расширен до поддержки TM1616, TM1620, TM1628, TM1630, TM1637, TM1638, TM1640, TM1650, TM1652 и TM1668",
"propInfo": {
"int": "Период времени в секундах обновления информации на экране по конкретному элементу.",
"chip": "Номер чипа TM1637 или TM1638",
"numDigits": "Число цифр на дисплее",
"DIO": "Номер пина данных",
"CLK": "Номер пина часового сигнала",
"intensity": "Яркость 0-7",
"on": "Вкл/выкл при старте 1/0",
"STB": "Номер пина стекового сигнала - не используется на определенных моделях",
"id2show": "id элемента конфигурации для отображения. Если пустая строка, то дисплей использует свою переменную. Если указать несколько значений через запятую, то все данные будут последовательно выводиться в строку."
},
"funcInfo": [
{
"name": "noBacklight",
"descr": "Выключить подсветку",
"params": []
},
{
"name": "backlight",
"descr": "Включить подсветку",
"params": []
},
{
"name": "noDisplay",
"descr": "Спрятать все данные",
"params": []
},
{
"name": "display",
"descr": "Показать данные на экране",
"params": []
},
{
"name": "toggle",
"descr": "Переключает видимость значений на экране",
"params": []
},
{
"name": "x",
"descr": "Устанавливает первую координату",
"params": ["Номер строки первого символа"]
},
{
"name": "y",
"descr": "Устанавливает вторую координату",
"params": ["Номер столбца первого символа"]
},
{
"name": "descr",
"descr": "Задает приставку слева от значения",
"params": ["Строка"]
},
{
"name": "id2show",
"descr": "Задает ИД элемента, значение которого хотим отображать на экране",
"params": ["Имя элемента конфигурации"]
}
]
},
"defActive": true,
"usedLibs": {
"esp32_4mb": [
"https://github.com/maxint-rd/TM16xx",
"adafruit/Adafruit GFX Library @ ^1.11.5"
],
"esp8266_4mb": [
"https://github.com/maxint-rd/TM16xx",
"adafruit/Adafruit GFX Library @ ^1.11.5"
],
"esp8266_1mb": [
"https://github.com/maxint-rd/TM16xx",
"adafruit/Adafruit GFX Library @ ^1.11.5"
],
"esp8266_1mb_ota": [
"https://github.com/maxint-rd/TM16xx",
"adafruit/Adafruit GFX Library @ ^1.11.5"
],
"esp8285_1mb": [
"https://github.com/maxint-rd/TM16xx",
"adafruit/Adafruit GFX Library @ ^1.11.5"
],
"esp8285_1mb_ota": [
"https://github.com/maxint-rd/TM16xx",
"adafruit/Adafruit GFX Library @ ^1.11.5"
],
"esp8266_2mb": [
"https://github.com/maxint-rd/TM16xx",
"adafruit/Adafruit GFX Library @ ^1.11.5"
],
"esp8266_2mb_ota": [
"https://github.com/maxint-rd/TM16xx",
"adafruit/Adafruit GFX Library @ ^1.11.5"
]
}
}

View File

@@ -39,18 +39,18 @@ class RTC : public IoTItem {
return this;
}
ulong getRtcUnixTime() {
return _watch->gettimeUnix();
unsigned long getRtcUnixTime() {
return _watch->gettimeUnix() - jsonReadInt(settingsFlashJson, F("timezone")) * 60 * 60;
}
void onModuleOrder(String &key, String &value) {
if (key == "setUTime") {
char *stopstring;
ulong ut = strtoul(value.c_str(), &stopstring, 10);
unsigned long ut = strtoul(value.c_str(), &stopstring, 10);
_watch->settimeUnix(ut);
SerialPrint("i", F("RTC"), "Устанавливаем время: " + value);
} else if (key == "setSysTime") {
_watch->settimeUnix(unixTime);
_watch->settimeUnix(unixTime + jsonReadInt(settingsFlashJson, F("timezone")) * 60 * 60);
SerialPrint("i", F("RTC"), F("Запоминаем системное время"));
}
}

View File

@@ -0,0 +1,432 @@
#include "Global.h"
#include "classes/IoTItem.h"
#define MONITOR_SERIAL Serial
#define RADAR_SERIAL Serial1
// #define RADAR_RX_PIN 32
// #define RADAR_TX_PIN 33
#include <ld2410.h>
// ld2410 radar;
ld2410 *radar = nullptr;
ld2410 *instanceradar(uint8_t _rx, uint8_t _tx)
{
if (!radar)
{ // Если библиотека ранее инициализировалась, т о просто вернем указатель
// Инициализируем библиотеку
radar = new ld2410();
// radar->begin(); // При необходимости делаем begin библиотеке
RADAR_SERIAL.begin(256000, SERIAL_8N1, _rx, _tx); // UART for monitoring the radar
if (radar->begin(RADAR_SERIAL))
{
SerialPrint("i", "LD2410", "Radar sensor подключен");
SerialPrint("i", "LD2410", "Connect LD2410 radar TX to GPIO: " + String(_rx));
SerialPrint("i", "LD2410", "Connect LD2410 radar RX to GPIO: " + String(_tx));
SerialPrint("i", "LD2410", "LD2410 firmware version: " + String(radar->firmware_major_version));
SerialPrint("i", "LD2410", "LD2410 firmware version: " + String(radar->firmware_minor_version));
SerialPrint("i", "LD2410", "LD2410 firmware version: " + String(radar->firmware_bugfix_version));
}
else
{
SerialPrint("i", "LD2410", "Radar sensor не подключен");
}
}
return radar;
}
int presence = 0;
int presence_last = 0;
int movement = 0;
int movement_last = 0;
int distance = 0;
int distance_last = 0;
int energy = 0;
int energy_last = 0;
int err = 0;
uint32_t lastReadingP = 0;
uint32_t lastReadingM = 0;
uint32_t lastReadingD = 0;
uint32_t lastReadingE = 0;
bool radarConnected = false;
// датчик присутствия
class ld2410m : public IoTItem
{
private:
int _ticker;
uint8_t _rx, _tx;
public:
//=======================================================================================================
// setup()
ld2410m(String parameters) : IoTItem(parameters)
{
jsonRead(parameters, "ticker", _ticker);
String tmp;
jsonRead(parameters, "RX", tmp);
_rx = tmp.toInt();
jsonRead(parameters, "TX", tmp);
_tx = tmp.toInt();
}
void loop()
{
instanceradar(_rx, _tx)->read();
if (instanceradar(_rx, _tx)->isConnected() && millis() - lastReadingP > 1000) // Report every 1000ms
{
lastReadingP = millis();
err = 0;
presence = instanceradar(_rx, _tx)->presenceDetected();
if (instanceradar(_rx, _tx)->stationaryTargetDetected())
{
movement = 0;
distance = instanceradar(_rx, _tx)->stationaryTargetDistance();
energy = instanceradar(_rx, _tx)->stationaryTargetEnergy();
}
if (instanceradar(_rx, _tx)->movingTargetDetected())
{
movement = 1;
distance = instanceradar(_rx, _tx)->movingTargetDistance();
energy = instanceradar(_rx, _tx)->movingTargetEnergy();
}
if (presence != presence_last)
{
value.valD = int(presence);
regEvent(value.valD, "ld2410m");
presence_last = presence;
// SerialPrint("i", "LD2410", "присутствие: " + String(int(presence)));
}
if (presence && movement != movement_last)
{
value.valD = int(presence);
regEvent(value.valD, "ld2410m");
}
if (presence && _ticker)
{
value.valD = int(presence);
regEvent(value.valD, "ld2410m");
presence_last = presence;
}
}
if (!instanceradar(_rx, _tx)->isConnected())
{
if (err == 0)
{
// value.valD = "Err";
// regEvent(value.valD, "ld2410m");
// SerialPrint("E", "LD2410", "Radar sensor ошибка получения данных");
}
err = 1;
}
}
IoTValue execute(String command, std::vector<IoTValue> &param)
{
if (command == "setmaxvalues")
{
if (param[0].isDecimal && param[1].isDecimal && param[2].isDecimal)
{
uint8_t newMovingMaxDistance = param[0].valD;
uint8_t newStationaryMaxDistance = param[1].valD;
uint16_t inactivityTimer = param[2].valD;
if (newMovingMaxDistance > 0 && newStationaryMaxDistance > 0 && newMovingMaxDistance <= 8 && newStationaryMaxDistance <= 8)
{
if (instanceradar(_rx, _tx)->setMaxValues(newMovingMaxDistance, newStationaryMaxDistance, inactivityTimer))
{
SerialPrint("i", "LD2410", "Параметры установлены. Перезапустите датчик");
}
else
{
SerialPrint("E", "LD2410", "Ошибка записи параметров.");
}
}
else
{
SerialPrint("E", "LD2410", "Заданы не корректные параметры. Диапазон от 1 до 8 ");
}
}
}
if (command == "setsensitivity")
{
if (param[0].isDecimal && param[1].isDecimal && param[2].isDecimal)
{
uint8_t gate = param[0].valD;
uint8_t motionSensitivity = param[1].valD;
uint16_t stationarySensitivity = param[2].valD;
if (motionSensitivity >= 0 && stationarySensitivity >= 0 && motionSensitivity <= 100 && stationarySensitivity <= 100)
{
if (instanceradar(_rx, _tx)->setGateSensitivityThreshold(gate, motionSensitivity, stationarySensitivity))
{
SerialPrint("i", "LD2410", "Параметры установлены. Перезапустите датчик");
}
else
{
SerialPrint("E", "LD2410", "Ошибка записи параметров.");
}
}
else
{
SerialPrint("E", "LD2410", "Заданы не корректные параметры. Диапазон от 1 до 100 ");
}
}
}
if (command == "enableengineeringmode")
{
if (instanceradar(_rx, _tx)->requestStartEngineeringMode())
{
SerialPrint("i", "LD2410", "Параметры установлены. Перезапустите датчик");
}
else
{
SerialPrint("E", "LD2410", "Ошибка записи параметров.");
}
}
if (command == "disableengineeringmode")
{
if (instanceradar(_rx, _tx)->requestEndEngineeringMode())
{
SerialPrint("i", "LD2410", "Параметры установлены. Перезапустите датчик");
}
else
{
SerialPrint("E", "LD2410", "Ошибка записи параметров.");
}
}
if (command == "restart")
{
if (instanceradar(_rx, _tx)->requestRestart())
{
SerialPrint("i", "LD2410", "Датчик перезапущен");
}
else
{
SerialPrint("E", "LD2410", "Ошибка перезапуска датчика.");
}
}
if (command == "readversion")
{
if (instanceradar(_rx, _tx)->requestFirmwareVersion())
{
SerialPrint("i", "LD2410", (String)instanceradar(_rx, _tx)->firmware_major_version);
SerialPrint("i", "LD2410", (String)instanceradar(_rx, _tx)->firmware_minor_version);
}
else
{
SerialPrint("E", "LD2410", "Ошибка получения версии.");
}
}
if (command == "factoryreset")
{
if (instanceradar(_rx, _tx)->requestFactoryReset())
{
SerialPrint("i", "LD2410", "Параметры установлены. Перезапустите датчик");
}
else
{
SerialPrint("E", "LD2410", "Ошибка сброса параметров.");
}
}
}
~ld2410m(){};
};
//---------------------------------------------------------------------------
// движение / стационарное - присутствие
class ld2410t : public IoTItem
{
private:
uint8_t _rx, _tx;
public:
//=======================================================================================================
// setup()
ld2410t(String parameters) : IoTItem(parameters)
{
String tmp;
jsonRead(parameters, "RX", tmp);
_rx = tmp.toInt();
jsonRead(parameters, "TX", tmp);
_tx = tmp.toInt();
}
void loop()
{
instanceradar(_rx, _tx)->read();
if (instanceradar(_rx, _tx)->isConnected() && millis() - lastReadingM > 1000) // Report every 1000ms
{
lastReadingM = millis();
err = 0;
presence = instanceradar(_rx, _tx)->presenceDetected();
if (instanceradar(_rx, _tx)->stationaryTargetDetected())
{
movement = 0;
// distance = instanceradar(_rx, _tx)->stationaryTargetDistance();
// energy = instanceradar(_rx, _tx)->stationaryTargetEnergy();
}
if (instanceradar(_rx, _tx)->movingTargetDetected())
{
movement = 1;
// distance = instanceradar(_rx, _tx)->movingTargetDistance();
// energy = instanceradar(_rx, _tx)->movingTargetEnergy();
}
}
if (presence == 0 && movement_last != 0)
{
movement = 0;
}
if (movement != movement_last)
{
value.valD = int(movement);
regEvent(value.valD, "ld2410t");
movement_last = movement;
}
}
~ld2410t(){};
};
//---------------------------------------------------------------------------
// дистанция
class ld2410d : public IoTItem
{
private:
uint8_t _rx, _tx;
public:
//=======================================================================================================
// setup()
ld2410d(String parameters) : IoTItem(parameters)
{
String tmp;
jsonRead(parameters, "RX", tmp);
_rx = tmp.toInt();
jsonRead(parameters, "TX", tmp);
_tx = tmp.toInt();
}
void loop()
{
instanceradar(_rx, _tx)->read();
if (instanceradar(_rx, _tx)->isConnected() && millis() - lastReadingD > 1000) // Report every 1000ms
{
lastReadingD = millis();
err = 0;
presence = instanceradar(_rx, _tx)->presenceDetected();
if (instanceradar(_rx, _tx)->stationaryTargetDetected())
{
// movement = 0;
distance = instanceradar(_rx, _tx)->stationaryTargetDistance();
// energy = instanceradar(_rx, _tx)->stationaryTargetEnergy();
}
if (instanceradar(_rx, _tx)->movingTargetDetected())
{
// movement = 1;
distance = instanceradar(_rx, _tx)->movingTargetDistance();
// energy = instanceradar(_rx, _tx)->movingTargetEnergy();
}
if (presence == 0 && distance_last != 0)
{
distance = 0;
}
if (distance != distance_last)
{
value.valD = int(distance);
regEvent(value.valD, "ld2410d");
distance_last = distance;
}
}
}
~ld2410d(){};
};
//---------------------------------------------------------------------------
// энергия
class ld2410e : public IoTItem
{
private:
uint8_t _rx, _tx;
public:
//=======================================================================================================
// setup()
ld2410e(String parameters) : IoTItem(parameters)
{
String tmp;
jsonRead(parameters, "RX", tmp);
_rx = tmp.toInt();
jsonRead(parameters, "TX", tmp);
_tx = tmp.toInt();
}
void loop()
{
instanceradar(_rx, _tx)->read();
if (instanceradar(_rx, _tx)->isConnected() && millis() - lastReadingE > 1000) // Report every 1000ms
{
lastReadingE = millis();
err = 0;
presence = instanceradar(_rx, _tx)->presenceDetected();
if (instanceradar(_rx, _tx)->stationaryTargetDetected())
{
// movement = 0;
// distance = instanceradar(_rx, _tx)->stationaryTargetDistance();
energy = instanceradar(_rx, _tx)->stationaryTargetEnergy();
}
if (instanceradar(_rx, _tx)->movingTargetDetected())
{
// movement = 1;
// distance = instanceradar(_rx, _tx)->movingTargetDistance();
energy = instanceradar(_rx, _tx)->movingTargetEnergy();
}
if (presence == 0 && energy_last != 0)
{
energy = 0;
}
if (energy != energy_last)
{
value.valD = int(energy);
regEvent(value.valD, "ld2410e");
// value = Value;
// regEvent((String)(int)value.valD, F("ld2410e"), false, true);
// SerialPrint("i", "LD2410", "Radar sensor энергия: " + String(energy));
energy_last = energy;
}
}
}
~ld2410e(){};
};
//---------------------------------------------------------------------------
void *getAPI_ld2410(String subtype, String param)
{
if (subtype == F("ld2410m"))
{
return new ld2410m(param);
}
else if (subtype == F("ld2410t"))
{
return new ld2410t(param);
}
else if (subtype == F("ld2410d"))
{
return new ld2410d(param);
}
else if (subtype == F("ld2410e"))
{
return new ld2410e(param);
}
else
{
return nullptr;
}
}

View File

@@ -0,0 +1,92 @@
{
"menuSection": "Сенсоры",
"configItem": [
{
"global": 0,
"name": "LD2410 Датчик присутствия",
"type": "Reading",
"subtype": "ld2410m",
"id": "ld2410m",
"widget": "anydataDef",
"page": "Сенсоры",
"descr": "Присутствие",
"RX": 32,
"TX": 33,
"val": 0,
"round": 0,
"ticker": 0
},
{
"global": 0,
"name": "LD2410 подвижность объета",
"type": "Reading",
"subtype": "ld2410t",
"id": "ld2410t",
"widget": "anydataDef",
"page": "Сенсоры",
"descr": "Движение",
"RX": 32,
"TX": 33,
"val": 0,
"round": 0
},
{
"global": 0,
"name": "LD2410 дистанция до объекта",
"type": "Reading",
"subtype": "ld2410d",
"id": "ld2410d",
"widget": "anydataCm",
"page": "Сенсоры",
"descr": "Дистанция",
"RX": 32,
"TX": 33,
"val": 0,
"round": 0
},
{
"global": 0,
"name": "LD2410 отраженная энергия",
"type": "Reading",
"subtype": "ld2410e",
"id": "ld2410e",
"widget": "anydataHum",
"page": "Сенсоры",
"descr": "Энергия",
"RX": 32,
"TX": 33,
"val": 0,
"round": 0
}
],
"about": {
"authorName": "AVAKS",
"authorContact": "https://t.me/avaks",
"authorGit": "https://github.com/avaksru",
"exampleURL": "https://iotmanager.org/wiki",
"specialThanks": "Mitchel https://t.me/Mit4bmw",
"moduleName": "ld2410",
"moduleVersion": "1.0",
"usedRam": {
"esp32_4mb": 15,
"esp8266_4mb": 0
},
"subTypes": [
"ld2410m",
"ld2410t",
"ld2410d",
"ld2410e"
],
"title": "Радарный датчик присутствия человека Hi-Link HLK-LD2410",
"moduleDesc": "Умный датчик, который измеряет расстояние, определяет стоит объект или двигается. Умеет разбивать зоны движения (всего можно до 8 зон задать). ",
"propInfo": {
"ticker": "1 - генерирует событие каждую секунду пока обнаружено присутствие, 0 - событие генереруется только один раз когда присутствие обнаружено или когда обьект вышел из поля обнаружения датчика"
}
},
"defActive": false,
"usedLibs": {
"esp32_4mb": [
"ncmreynolds/ld2410@^0.1.3"
]
}
}

View File

@@ -238,6 +238,18 @@ int jsonReadInt(const String& json, String name, bool e) {
return doc[name].as<int>();
}
long int jsonReadLInt(const String& json, String name, bool e) {
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
DeserializationError error = deserializeJson(doc, json);
if (error) {
if (e) {
SerialPrint("E", F("jsonRead"), error.f_str());
jsonErrorDetected();
}
}
return doc[name].as<long int>();
}
// depricated========================================================================
String jsonWriteStr(String& json, String name, String value, bool e) {
DynamicJsonDocument doc(JSON_BUFFER_SIZE);

View File

@@ -16,8 +16,8 @@ void stInit() {
void updateDeviceStatus() {
String ret;
String serverIP;
jsonRead(settingsFlashJson, F("serverip"), serverIP);
String serverIP = "http://iotmanager.org";
// jsonRead(settingsFlashJson, F("serverip"), serverIP);
String url = serverIP + F("/projects/esprebootstat.php");
// SerialPrint("i", "Stat", "url " + url);
if ((WiFi.status() == WL_CONNECTED)) {

View File

@@ -204,4 +204,23 @@ void cleanString(String& str) {
for (size_t i = 0; i < str.length(); i++) {
if (allowedChars.indexOf(str.charAt(i)) == -1) str.setCharAt(i, ' ');
}
}
std::vector<String> splitStr(const String& str, const String& delimiter) {
std::vector<String> result;
size_t newPos, pos = 0;
while ((newPos = str.indexOf(delimiter, pos)) != -1) {
result.push_back(str.substring(pos, newPos));
pos = newPos + delimiter.length();
}
result.push_back(str.substring(pos));
return result;
}
bool strInVector(const String& str, const std::vector<String>& vec) {
for (size_t i = 0; i < vec.size(); i++) {
if (vec[i] == str) return true;
}
return false;
}

View File

@@ -2,7 +2,7 @@
#include "Global.h"
#include "utils/StringUtils.h"
static const char* TIME_FORMAT PROGMEM = "%02d:%02d"; //:%02d";
static const char* TIME_FORMAT PROGMEM = "%02d:%02d:%02d";
static const char* TIME_FORMAT_WITH_DAYS PROGMEM = "%dd %02d:%02d";
const String prettySeconds(unsigned long time_s) {