64 Commits

Author SHA1 Message Date
Dmitry Borisenko
6fe10441b1 Merge pull request #112 from biveraxe/ver3dev
Завершаем перенос ButtonOut в новую систему классов, требуется дорабо…
2022-01-12 13:10:43 +01:00
c002bafc1c Завершаем перенос ButtonOut в новую систему классов, требуется доработка взаимодействия с виджитами 2021-12-31 10:55:38 +03:00
IoT Manager
6b481de207 Merge pull request #111 from biveraxe/ver3dev
Класс IoTSensor вроде готов
2021-12-31 01:52:44 +01:00
b0fb71832c Убираем глобальные переменные из модулей, есть веростность, что получится при линковке не включать модули, которые исключены из api.cpp 2021-12-30 12:11:19 +03:00
6a7653c7ff Добавляем IoTVariable для дальнейшей доработки 2021-12-30 11:56:08 +03:00
ee94853ad9 Переносм функционал физической кнопки в класс IoTSensor 2021-12-28 11:04:14 +03:00
ede9092a73 Исправляем проблему начала измерений. Не все строки перенесены были из основной версии модуля. 2021-12-27 22:47:30 +03:00
30cf9cc3bb Исправляем ошибку при очистке глобальных списков в модуле Dallas 2021-12-27 22:05:23 +03:00
41f4be6139 Добавляем работу сенсоров с несколькими измерениями. Добавляем первую версию класса Variable. 2021-12-27 21:24:55 +03:00
IoT Manager
c8df0de972 Merge pull request #109 from biveraxe/ver3dev
Первая интеграция глобальных векторов в ver3dev
2021-12-26 18:39:57 +01:00
bebea0732a Добавляем в модуль далласа поддержку нескольких линий одновременно 2021-12-24 20:03:38 +03:00
5fecb51d69 Добавляем комментарии и наводим порядок 2021-12-23 13:02:06 +03:00
faa865e78d Добавляем механизм глобальных векторов для модулей и сенсоров. Модуль Dallas полностью интегрирован поновому 2021-12-23 09:09:26 +03:00
Dmitry Borisenko
66f21a5001 Merge pull request #106 from DmitryBorisenko33/ver3
добавил BH1750
2021-12-19 22:56:01 +01:00
Dmitry Borisenko
e9032365b4 добавил BH1750 2021-12-19 22:52:26 +01:00
Dmitry Borisenko
f39b16f787 Merge pull request #105 from DmitryBorisenko33/ver3
добавил название параметра
2021-12-19 22:37:45 +01:00
Dmitry Borisenko
fd09ec9d6b добавил название параметра 2021-12-19 22:36:52 +01:00
Dmitry Borisenko
9ce2cea94a Merge pull request #104 from DmitryBorisenko33/ver3
добавил LCD
2021-12-19 22:21:05 +01:00
Dmitry Borisenko
b0e06707bd добавил LCD 2021-12-19 22:19:35 +01:00
Dmitry Borisenko
cf7599e367 Merge pull request #103 from DmitryBorisenko33/ver3
Merge pull request #1 from IoTManagerProject/ver3
2021-12-19 21:26:50 +01:00
Dmitry Borisenko
5b87cedd78 Merge pull request #1 from IoTManagerProject/ver3
fix
2021-12-15 21:09:54 +01:00
Dmitry Borisenko
5e24d7aec0 Merge pull request #99 from DmitryBorisenko33/ver3
добавил AHTX0 HDC1080
2021-12-15 21:08:34 +01:00
Dmitry Borisenko
a4fe4f6c1a добавил AHTX0 HDC1080 2021-12-15 21:06:53 +01:00
Dmitry Borisenko
3d93141e2c Merge pull request #98 from avaksru/ver3
lunix fix
2021-12-15 21:04:21 +01:00
avaksru
e9d3750e1b linux fix 2 2021-12-15 18:40:32 +03:00
avaksru
03b347b630 lunix fix 2021-12-15 17:20:44 +03:00
Dmitry Borisenko
3fc86fb173 Merge pull request #97 from DmitryBorisenko33/ver3
Возможность добавлять любой сенсор
2021-12-15 00:24:59 +01:00
Dmitry Borisenko
9dde5942f0 test 2021-12-15 00:23:01 +01:00
Dmitry Borisenko
3bb13de0a9 Merge branch 'IoTManagerProject:ver3' into ver3 2021-12-15 00:20:04 +01:00
Dmitry Borisenko
f5b5bd78ec 304 2021-12-14 23:56:30 +01:00
Dmitry Borisenko
b68fa1b0f6 финальная версия с сенсором 2021-12-14 23:55:17 +01:00
Dmitry Borisenko
1529da443b wifi 2021-12-14 23:22:30 +01:00
Dmitry Borisenko
8984a8d143 кастомный сенсор 2021-12-14 23:20:14 +01:00
Dmitry Borisenko
93a6a24254 новый сенсор 2021-12-14 23:08:35 +01:00
Dmitry Borisenko
d2a375dc9e добавил шаблон любого сенсора 2021-12-14 23:05:42 +01:00
IoT Manager
acf9e2bd5d Merge pull request #96 from biveraxe/ver3
Исправляем ошибку чтения температуры для Dallas на ESP32 и добавляем адресацию
2021-12-14 17:55:52 +01:00
4a946ff3eb Исправляем ошибку чтения температуры для Dallas на ESP32 и добавляем возможность указать для каждого датчика Dallas Ds18b20 свой адрес на шине. 2021-12-14 17:02:42 +03:00
Dmitry Borisenko
9c1604e9cc Merge pull request #95 from DmitryBorisenko33/ver3
fixed preset
2021-12-14 13:55:33 +01:00
Dmitry Borisenko
bc8f683c79 fixed preset 2021-12-14 13:53:11 +01:00
Dmitry Borisenko
65c1449cde 304 2021-12-13 23:51:04 +01:00
Dmitry Borisenko
1a88298fd4 esp32 compiling version 2021-12-13 23:35:29 +01:00
Dmitry Borisenko
fbb5ba7e64 partitions 2021-12-13 23:23:12 +01:00
Dmitry Borisenko
ca9444bbd9 add castom partition for esp32 2021-12-13 22:43:53 +01:00
IoT Manager
e9f36e7d20 Merge pull request #94 from avaksru/ver3
add weekday, IP, ESP_NAME
2021-12-13 21:03:57 +01:00
avaksru
32350ddaf1 webUI 2021-12-13 16:40:44 +03:00
avaksru
d083fbf9cf websocket & function 2021-12-13 16:26:43 +03:00
avaksru
e46a6247f9 del 2021-12-13 10:03:27 +03:00
avaksru
b125986fb3 telegram add weekday, IP, ESP_NAME, date 2021-12-13 09:59:43 +03:00
avaksru
a020c09928 add weekday, IP, ESP_NAME 2021-12-13 09:43:10 +03:00
Dmitry Borisenko
7c423ddea6 test 2021-12-07 19:51:46 +01:00
Dmitry Borisenko
f28bafa277 Исправил косяк со слетающим config json 2021-12-07 05:58:06 +01:00
Dmitry Borisenko
35923eca7d merge pr 2021-12-07 05:16:19 +01:00
Dmitry Borisenko
495488a52f Merge pull request #93 from biveraxe/biveraddons
Увеличиваем макимальное количество возможных кнопок до 8 для ESP32
2021-12-07 05:06:31 +01:00
96b80dfd28 Увеличиваем макимальное количество возможных кнопок до 8 для ESP32 2021-12-04 23:50:49 +03:00
Dmitry Borisenko
b8f2cb2716 версия 303 2021-12-03 21:41:17 +01:00
Dmitry Borisenko
bb5eed987e Merge pull request #92 from biveraxe/biveraddons
Добавки от Biver
2021-12-03 21:33:16 +01:00
2b1ab1df50 Исправляем ошибку в алгоритме чтения директории. openNextFile() возвращает файл. 2021-12-03 11:18:48 +03:00
f668b5783e Удаляем мусор от касперского 7 строка и добавляем возможность редактировать CSV в веб-редакторе в файле edit.htm 2021-12-03 11:04:55 +03:00
70d2926f55 Добавляем пункт 25.Датчик температуры, влажности SHT2x, HTU2x and Si70xx 2021-12-03 10:51:10 +03:00
f1c573b882 Добавляем пункт 25.Датчик температуры, влажности SHT2x, HTU2x and Si70xx 2021-12-03 10:34:25 +03:00
de2075664b Интегрируем датчик SHT20 в основные фалы проекта кроме set.device.json 2021-12-03 10:30:56 +03:00
55ee70849f Добавляем библиотеку SHT2x к проекту 2021-12-03 10:05:44 +03:00
725cf26d41 Добавляем файлы для нового сенсора SHT20 2021-12-03 10:03:20 +03:00
7e5b611c23 Добавляем использование всех пинов на ESP32 в качестве кнопки путем явного указания режима порта. 2021-12-03 09:52:45 +03:00
103 changed files with 2642 additions and 723 deletions

54
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,54 @@
{
"files.associations": {
"array": "cpp",
"atomic": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"fstream": "cpp",
"functional": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"ostream": "cpp",
"numeric": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"regex": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"typeinfo": "cpp",
"chrono": "cpp",
"mutex": "cpp",
"ratio": "cpp",
"system_error": "cpp",
"cstddef": "cpp",
"unordered_set": "cpp",
"algorithm": "cpp",
"iomanip": "cpp",
"memory": "cpp",
"string": "cpp"
},
"cmake.configureOnOpen": false
}

View File

@@ -1,37 +1,37 @@
{
"name": "IoTmanager",
"chipID": "",
"apssid": "IoTmanager",
"appass": "",
"routerssid": "XChangeWIFI",
"routerpass": "XCh@WIFI",
"timezone": 1,
"ntp": "pool.ntp.org",
"mqttServer": "91.204.228.124",
"mqttPort": 1883,
"mqttPrefix": "/iotTest3",
"mqttUser": "rise",
"mqttPass": "23ri22se32",
"mqttServer2": "M2.WQTT.RU",
"mqttPort2": 8021,
"mqttPrefix2": "/iotTest3",
"mqttUser2": "rise",
"mqttPass2": "hostel3333",
"scen": "1",
"telegramApi": "1416711569:AAEI0j83GmXqwzb_gnK1B0Am0gDwZoJt5xo",
"telegonof": "0",
"teleginput": "0",
"autos": "1",
"weblogin": "admin",
"webpass": "admin",
"MqttIn": "0",
"MqttOut": "0",
"blink": "0",
"oneWirePin": "2",
"serverip": "http://206.189.49.244",
"uart": "0",
"uartS": "9600",
"uartTX": "12",
"uartRX": "13",
"grafmax": "0"
"name": "IoTmanager",
"chipID": "",
"apssid": "IoTmanager",
"appass": "",
"routerssid": "rise",
"routerpass": "hostel3333",
"timezone": 3,
"ntp": "pool.ntp.org",
"mqttServer": "live-control.ru",
"mqttPort": 1883,
"mqttPrefix": "/IotManager",
"mqttUser": "IotManager:guest",
"mqttPass": "guest",
"mqttServer2": "",
"mqttPort2": 0,
"mqttPrefix2": "",
"mqttUser2": "",
"mqttPass2": "",
"scen": "1",
"telegramApi": "",
"telegonof": "0",
"teleginput": "0",
"autos": "1",
"weblogin": "admin",
"webpass": "admin",
"MqttIn": "0",
"MqttOut": "0",
"blink": "0",
"oneWirePin": "2",
"serverip": "http://206.189.49.244",
"uart": "0",
"uartS": "9600",
"uartTX": "12",
"uartRX": "13",
"grafmax": "0"
}

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -0,0 +1,63 @@
html, body {
position: relative;
width: 100%;
height: 100%;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
-webkit-padding: 0.4em 0;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}

View File

@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>LiveControl v 0.3.2</title>
<link rel="icon" type="image/png" href="/favicon.ico" />
<link rel="stylesheet" href="/dashboard/global.css" />
<link rel="stylesheet" href="/dashboard/build/bundle.css" />
<script defer src="/dashboard/build/bundle.js" onload="loadPage()"></script>
<script>
function get_cookie ( cookie_name ){
var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)' );
if ( results )
return ( unescape ( results[2] ) );
else
return null;
}
if (get_cookie("darktheme") == "true"){
var myColor = "#1d3040";
document.write('\
<style>\
body{\
background-color: '+myColor+';\
}\
</style>\
');
}
function loadPage() {
document.getElementById("status").style.display = "none";
}
</script>
<style>
.rotate-shadows {
width: 220px;
height: 220px;
margin:0 auto;
position: relative;
}
.rotate-shadows:after,
.rotate-shadows:before {
content: "";
border-radius: 150%;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: center center;
}
.rotate-shadows:before {
box-shadow: inset 0 20px 0 rgba(0, 250, 250, 0.2),
inset 20px 0 0 rgba(0, 200, 200, 0.2),
inset 0 -20px 0 rgba(0, 150, 200, 0.2),
inset -20px 0 0 rgba(0, 200, 250, 0.2);
animation: rotate-before 9s -0.5s linear infinite;
}
.rotate-shadows:after {
box-shadow: inset 0 20px 0 rgba(250, 250, 0, 0.2),
inset 20px 0 0 rgba(250, 200, 0, 0.2),
inset 0 -20px 0 rgba(250, 150, 0, 0.2),
inset -20px 0 0 rgba(250, 100, 0, 0.2);
animation: rotate-after 9s -0.5s linear infinite;
}
@keyframes rotate-after {
0% {
transform: rotateZ(0deg) scaleX(1) scaleY(1);
}
50% {
transform: rotateZ(180deg) scaleX(0.82) scaleY(0.95);
}
100% {
transform: rotateZ(360deg) scaleX(1) scaleY(1);
}
}
@keyframes rotate-before {
0% {
transform: rotateZ(0deg) scaleX(1) scaleY(1);
}
50% {
transform: rotateZ(-180deg) scaleX(0.95) scaleY(0.85);
}
100% {
transform: rotateZ(-360deg) scaleX(1) scaleY(1);
}
}
</style>
</head>
<body>
<p><div id="status" class="rotate-shadows"></div></p>
</body>
</html>

Binary file not shown.

Binary file not shown.

View File

@@ -31,4 +31,13 @@
0;output-value;txtid;anydata;Вывод;Температура;order*
0;logging;crtid;chart;Графики;История;order;val[any];int[60];cnt[100]*
0;logging;crtid;chart3;Графики;История;order;val[any];int[23:30];cnt[100];st[0]*
0;uptime;uptid;anydataTime;Системные;%name%#uptime;order;int[60]*
0;uptime;uptid;anydataTime;Системные;%name%#uptime;order;int[60]*
0;sht20;tmpid;anydataTemp;Сенсоры;Температура;1;c[1]
0;sht20;humid;anydataHum;Сенсоры;Влажность;2;c[1];int[50]*
0;sensor;anyid;anydata;Сенсоры;Параметр;1;c[1];int[10];type[HDC1080_temp];addr[0x76]
0;sensor;anyid;anydata;Сенсоры;Параметр;1;c[1];int[10];type[HDC1080_hum];addr[0x76]*
0;sensor;anyid;anydata;Сенсоры;Параметр;1;c[1];int[10];type[AHTX0_temp];addr[0x76]
0;sensor;anyid;anydata;Сенсоры;Параметр;1;c[1];int[10];type[AHTX0_hum];addr[0x76]*
0;sensor;anyid;anydata;Page;Tmp;1;c[0];k[0];int[10];type[LCD];val[any]
0;sensor;anyid;anydata;Page;Hum;1;c[8];k[1];int[10];type[LCD];val[any]*
0;sensor;anyid;anydata;Сенсоры;Параметр;1;c[1];int[10];type[type1];addr[0x76]*

View File

@@ -83,7 +83,7 @@ start = 0
cnt71 0
cnt72 0
end*
sens8 = 1 && on8b = 1
sens8 = 1 && on8 = 1
txt81 обнаружено
txt82 %date%
telegram often Обнаружено#движение

View File

@@ -1 +1,5 @@
Удалить;Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета
Удалить;Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета
0;uptime;upt;anydataTime;IoTManager;%name%#uptime;8;int[60]
0;output-value;ip;anydata;IoTManager;IP;9
0;output-value;time;anydata;IoTManager;Время#на#устройстве;10
0;output-value;weekday;anydata;IoTManager;День#недели#на#устройстве ;11
1 Удалить Удалить;Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета Тип элемента Id Виджет Имя вкладки Имя виджета Позиция виджета
2 0;uptime;upt;anydataTime;IoTManager;%name%#uptime;8;int[60]
3 0;output-value;ip;anydata;IoTManager;IP;9
4 0;output-value;time;anydata;IoTManager;Время#на#устройстве;10
5 0;output-value;weekday;anydata;IoTManager;День#недели#на#устройстве ;11

View File

@@ -1 +1,5 @@
//
timenow > 0
weekday %weekday%
ip %IP%
time %date%
end

Binary file not shown.

View File

@@ -0,0 +1 @@
.letter.svelte-1ls9om6{color:grey;font-size:60%;padding-left:0px;opacity:0.5}table.svelte-1ls9om6{margin:0px;background-color:#fafafa;line-height:1}td.svelte-1ls9om6{text-align:left;padding-left:1px}input[type="text"].svelte-1ls9om6{width:100%;padding:10px;border:1;box-shadow:0 0 15px 10px rgba(0, 0, 0, 0.06);border-radius:1px}.letter1.svelte-1ls9om6{color:grey;font-size:80%;padding-left:20px}.letter2.svelte-1ls9om6{text-align:left;padding-left:0px}select.svelte-1ls9om6{padding:10px;border-radius:10px;padding-left:20px;height:40px;font-size:13px}input[type="password"].svelte-1ls9om6{width:100%;padding:10px;border:1;box-shadow:0 0 15px 10px rgba(0, 0, 0, 0.06);border-radius:1px}input.svelte-1ls9om6:required:invalid:not(:placeholder-shown){border-color:crimson}.red.svelte-1ls9om6{border-color:crimson}progress.svelte-1ls9om6{height:4px}textarea.svelte-1ls9om6{width:100%}button.svelte-1ls9om6{height:30px;border-radius:4px;line-height:0}body.light-mode{background-color:white}body.dark-mode{background-color:#1d3040;color:#bfc2c7}body.dark-mode textarea.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode input.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode select.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode button.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode div.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode span.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}.Shutter.svelte-1ls9om6{background-color:hsl(200, 16%, 96%);color:blak;padding:10px;border-radius:5px}body.dark-mode .Shutter.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7;padding:10px;border-radius:5px}body.dark-mode table.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode .letter1.svelte-1ls9om6{color:#bfc2c7}body.dark-mode .letter2.svelte-1ls9om6{color:#bfc2c7}body.dark-mode b.svelte-1ls9om6{color:#bfc2c7}body.dark-mode button.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}h5.svelte-1ls9om6{display:inline}.box.svelte-hp9es9{width:93%;border:1px solid #aaa;border-radius:10px;box-shadow:10px 10px 8px rgba(0, 0, 0, 0.1);padding:1em;margin:0 0 1em 0}.tooltip.svelte-1vepdvs{border:1px solid #ddd;box-shadow:1px 1px 1px #ddd;background:rgb(185, 238, 241);border-radius:4px;padding:4px;position:absolute;color:black}.modal-background.svelte-10j5cq5{position:fixed;top:0;left:0;width:100%;height:100%;background:gray;opacity:0.8}.modal.svelte-10j5cq5{position:absolute;left:50%;top:50%;width:calc(100vw - 4em);max-width:32em;max-height:calc(100vh - 4em);overflow:auto;transform:translate(-50%, -50%);padding:1em;border-radius:0.2em;background:white}button.svelte-10j5cq5{display:block}.rotate-shadows.svelte-tks6xu{width:220px;height:220px;position:relative}.rotate-shadows.svelte-tks6xu:after,.rotate-shadows.svelte-tks6xu:before{content:"";border-radius:150%;position:absolute;top:0;left:0;width:100%;height:100%;transform-origin:center center}.rotate-shadows.svelte-tks6xu:before{box-shadow:inset 0 20px 0 rgba(0, 250, 250, 0.2), inset 20px 0 0 rgba(0, 200, 200, 0.2), inset 0 -20px 0 rgba(0, 150, 200, 0.2), inset -20px 0 0 rgba(0, 200, 250, 0.2);animation:svelte-tks6xu-rotate-before 9s -0.5s linear infinite}.rotate-shadows.svelte-tks6xu:after{box-shadow:inset 0 20px 0 rgba(250, 250, 0, 0.2), inset 20px 0 0 rgba(250, 200, 0, 0.2), inset 0 -20px 0 rgba(250, 150, 0, 0.2), inset -20px 0 0 rgba(250, 100, 0, 0.2);animation:svelte-tks6xu-rotate-after 9s -0.5s linear infinite}@keyframes svelte-tks6xu-rotate-after{0%{transform:rotateZ(0deg) scaleX(1) scaleY(1)}50%{transform:rotateZ(180deg) scaleX(0.82) scaleY(0.95)}100%{transform:rotateZ(360deg) scaleX(1) scaleY(1)}}@keyframes svelte-tks6xu-rotate-before{0%{transform:rotateZ(0deg) scaleX(1) scaleY(1)}50%{transform:rotateZ(-180deg) scaleX(0.95) scaleY(0.85)}100%{transform:rotateZ(-360deg) scaleX(1) scaleY(1)}}

Binary file not shown.

63
data_esp/setup/global.css Normal file
View File

@@ -0,0 +1,63 @@
html, body {
position: relative;
width: 100%;
height: 100%;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
-webkit-padding: 0.4em 0;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}

103
data_esp/setup/index.html Normal file
View File

@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>IotManager v 0.3.2</title>
<link rel="icon" type="image/png" href="/favicon.ico" />
<link rel="stylesheet" href="/setup/global.css" />
<link rel="stylesheet" href="/setup/build/bundle.css?0.3" />
<script defer src="/setup/build/bundle.js?0.3" onload="loadPage()"></script>
<script>
function get_cookie ( cookie_name ){
var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)' );
if ( results )
return ( unescape ( results[2] ) );
else
return null;
}
if (get_cookie("darktheme") == "true"){
var myColor = "#1d3040";
document.write('\
<style>\
body{\
background-color: '+myColor+';\
}\
</style>\
');
}
function loadPage() {
document.getElementById("status").style.display = "none";
}
</script>
<style>
.rotate-shadows {
width: 220px;
height: 220px;
margin:0 auto;
position: relative;
}
.rotate-shadows:after,
.rotate-shadows:before {
content: "";
border-radius: 150%;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: center center;
}
.rotate-shadows:before {
box-shadow: inset 0 20px 0 rgba(0, 250, 250, 0.2),
inset 20px 0 0 rgba(0, 200, 200, 0.2),
inset 0 -20px 0 rgba(0, 150, 200, 0.2),
inset -20px 0 0 rgba(0, 200, 250, 0.2);
animation: rotate-before 9s -0.5s linear infinite;
}
.rotate-shadows:after {
box-shadow: inset 0 20px 0 rgba(250, 250, 0, 0.2),
inset 20px 0 0 rgba(250, 200, 0, 0.2),
inset 0 -20px 0 rgba(250, 150, 0, 0.2),
inset -20px 0 0 rgba(250, 100, 0, 0.2);
animation: rotate-after 9s -0.5s linear infinite;
}
@keyframes rotate-after {
0% {
transform: rotateZ(0deg) scaleX(1) scaleY(1);
}
50% {
transform: rotateZ(180deg) scaleX(0.82) scaleY(0.95);
}
100% {
transform: rotateZ(360deg) scaleX(1) scaleY(1);
}
}
@keyframes rotate-before {
0% {
transform: rotateZ(0deg) scaleX(1) scaleY(1);
}
50% {
transform: rotateZ(-180deg) scaleX(0.95) scaleY(0.85);
}
100% {
transform: rotateZ(-360deg) scaleX(1) scaleY(1);
}
}
</style>
</head>
<body>
<p><div id="status" class="rotate-shadows"></div></p>
</body>
</html>

BIN
data_esp/setup/progress.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -1,34 +1,35 @@
{
"undef": "Ошибка",
"toggleBtn": "Кнопка переключатель",
"range": "Ползунок",
"inputDate": "Окно ввода даты",
"inputTime": "Окно ввода времени 1",
"inputTimeClock": "Окно ввода времени 2",
"inputDigit": "Окно ввода цифры",
"inputDigitTemp": "Окно ввода температуры",
"inputText": "Окно ввода текста",
"select": "Выпадающий список",
"chart": "График без точек",
"chart2": "График с точками",
"chart3": "График дневного расхода (столбики)",
"chart4": "График дневного расхода (плавный)",
"fillgauge": "Бочка",
"progress-line": "Линия",
"progress-round": "Круг",
"anydata": "Текст",
"anydataHum": "Влажность (%)",
"anydataPress": "Давление (mm)",
"anydataTemp": "Температура (°С)",
"anydataPpb": "Части на миллиард (ppb)",
"anydataPpm": "Части на миллион (ppm)",
"anydataVlt": "Напряжение (Vlt)",
"anydataAmp": "Сила тока (Amp)",
"anydataWtt": "Мощность (Wtt)",
"anydataWhr": "Энергия (Whr)",
"anydataHtz": "Частота (Htz)",
"anydataTime": "Манометр",
"alarm": "Тревожное сообщение 1",
"anydataAlarm": "Тревожное сообщение 2",
"na": "Без виджета"
}
{
"undef": "Ошибка",
"toggleBtn": "Переключатель",
"btn": "Кнопка",
"select": "Кнопка переключатель",
"range": "Ползунок",
"inputDate": "Окно ввода даты",
"inputTime": "Окно ввода времени 1",
"inputTimeClock": "Окно ввода времени 2",
"inputDigit": "Окно ввода цифры",
"inputDigitTemp": "Окно ввода температуры",
"inputText": "Окно ввода текста",
"chart": "График без точек",
"chart2": "График с точками",
"chart3": "График дневного расхода (столбики)",
"chart4": "График дневного расхода (плавный)",
"fillgauge": "Бочка",
"progress-line": "Линия",
"progress-round": "Круг",
"anydata": "Текст",
"anydataHum": "Влажность (%)",
"anydataPress": "Давление (mm)",
"anydataTemp": "Температура (°С)",
"anydataPpb": "Части на миллиард (ppb)",
"anydataPpm": "Части на миллион (ppm)",
"anydataVlt": "Напряжение (Vlt)",
"anydataAmp": "Сила тока (Amp)",
"anydataWtt": "Мощность (Wtt)",
"anydataWhr": "Энергия (Whr)",
"anydataHtz": "Частота (Htz)",
"anydataTime": "Манометр",
"alarm": "Тревожное сообщение 1",
"anydataAlarm": "Тревожное сообщение 2",
"na": "Без виджета"
}

View File

@@ -1,5 +1,6 @@
{
"widget": "anydata",
"after": "%",
"icon": "water"
}
"icon": "water",
"color": "#88AADF"
}

View File

@@ -1,5 +1,16 @@
{
"widget": "anydata",
"after": "°С",
"icon": "thermometer"
}
"icon": "thermometer",
"font": "OCR A Std",
"color": [
{ "level": -20, "value": "#0000CC" },
{ "level": -10, "value": "#0000CC" },
{ "level": 0, "value": "#0000CC" },
{ "level": 12, "value": "#3366FF" },
{ "level": 16, "value": "#33CCFF" },
{ "level": 18, "value": "#009933" },
{ "level": 30, "value": "#FF9900" },
{ "level": 40, "value": "red" }
]
}

View File

@@ -1,38 +1,37 @@
{
"name": "IoTmanager",
"chipID": "",
"apssid": "IoTmanager",
"appass": "",
"routerssid": "rise2",
"routerpass": "hostel3333",
"timezone": 1,
"ntp": "pool.ntp.org",
"mqttServer": "91.204.228.124",
"mqttPort": 1883,
"mqttPrefix": "/iotTest4",
"mqttUser": "rise",
"mqttPass": "23ri22se32",
"mqttServer2": "",
"mqttPort2": 0,
"mqttPrefix2": "",
"mqttUser2": "",
"mqttPass2": "",
"scen": "1",
"telegramApi": "1416711569:AAEI0j83GmXqwzb_gnK1B0Am0gDwZoJt5xo",
"telegonof": "0",
"teleginput": "0",
"autos": "1",
"weblogin": "admin",
"webpass": "admin",
"MqttIn": "0",
"MqttOut": "0",
"blink": "0",
"oneWirePin": "2",
"serverip": "http://206.189.49.244",
"uart": "0",
"uartS": "9600",
"uartTX": "12",
"uartRX": "13",
"grafmax": "0",
"gateAuto": "0"
}
"name": "IoTmanager",
"chipID": "",
"apssid": "IoTmanager",
"appass": "",
"routerssid": "Mikro",
"routerpass": "4455667788",
"timezone": 3,
"ntp": "pool.ntp.org",
"mqttServer": "live-control.ru",
"mqttPort": 1883,
"mqttPrefix": "/IotManager",
"mqttUser": "IotManager:guest",
"mqttPass": "guest",
"mqttServer2": "",
"mqttPort2": 0,
"mqttPrefix2": "",
"mqttUser2": "",
"mqttPass2": "",
"scen": "1",
"telegramApi": "",
"telegonof": "0",
"teleginput": "0",
"autos": "1",
"weblogin": "admin",
"webpass": "admin",
"MqttIn": "0",
"MqttOut": "0",
"blink": "0",
"oneWirePin": "2",
"serverip": "http://206.189.49.244",
"uart": "0",
"uartS": "9600",
"uartTX": "12",
"uartRX": "13",
"grafmax": "0"
}

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -0,0 +1,63 @@
html, body {
position: relative;
width: 100%;
height: 100%;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
-webkit-padding: 0.4em 0;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}

View File

@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>LiveControl v 0.3.2</title>
<link rel="icon" type="image/png" href="/favicon.ico" />
<link rel="stylesheet" href="/dashboard/global.css" />
<link rel="stylesheet" href="/dashboard/build/bundle.css" />
<script defer src="/dashboard/build/bundle.js" onload="loadPage()"></script>
<script>
function get_cookie ( cookie_name ){
var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)' );
if ( results )
return ( unescape ( results[2] ) );
else
return null;
}
if (get_cookie("darktheme") == "true"){
var myColor = "#1d3040";
document.write('\
<style>\
body{\
background-color: '+myColor+';\
}\
</style>\
');
}
function loadPage() {
document.getElementById("status").style.display = "none";
}
</script>
<style>
.rotate-shadows {
width: 220px;
height: 220px;
margin:0 auto;
position: relative;
}
.rotate-shadows:after,
.rotate-shadows:before {
content: "";
border-radius: 150%;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: center center;
}
.rotate-shadows:before {
box-shadow: inset 0 20px 0 rgba(0, 250, 250, 0.2),
inset 20px 0 0 rgba(0, 200, 200, 0.2),
inset 0 -20px 0 rgba(0, 150, 200, 0.2),
inset -20px 0 0 rgba(0, 200, 250, 0.2);
animation: rotate-before 9s -0.5s linear infinite;
}
.rotate-shadows:after {
box-shadow: inset 0 20px 0 rgba(250, 250, 0, 0.2),
inset 20px 0 0 rgba(250, 200, 0, 0.2),
inset 0 -20px 0 rgba(250, 150, 0, 0.2),
inset -20px 0 0 rgba(250, 100, 0, 0.2);
animation: rotate-after 9s -0.5s linear infinite;
}
@keyframes rotate-after {
0% {
transform: rotateZ(0deg) scaleX(1) scaleY(1);
}
50% {
transform: rotateZ(180deg) scaleX(0.82) scaleY(0.95);
}
100% {
transform: rotateZ(360deg) scaleX(1) scaleY(1);
}
}
@keyframes rotate-before {
0% {
transform: rotateZ(0deg) scaleX(1) scaleY(1);
}
50% {
transform: rotateZ(-180deg) scaleX(0.95) scaleY(0.85);
}
100% {
transform: rotateZ(-360deg) scaleX(1) scaleY(1);
}
}
</style>
</head>
<body>
<p><div id="status" class="rotate-shadows"></div></p>
</body>
</html>

Binary file not shown.

View File

@@ -1 +1,5 @@
Удалить;Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета
Удалить;Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета
0;uptime;upt;anydataTime;IoTManager;%name%#uptime;8;int[60]
0;output-value;ip;anydata;IoTManager;IP;9
0;output-value;time;anydata;IoTManager;Время#на#устройстве;10
0;output-value;weekday;anydata;IoTManager;День#недели#на#устройстве ;11
1 Удалить Удалить;Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета Тип элемента Id Виджет Имя вкладки Имя виджета Позиция виджета
2 0;uptime;upt;anydataTime;IoTManager;%name%#uptime;8;int[60]
3 0;output-value;ip;anydata;IoTManager;IP;9
4 0;output-value;time;anydata;IoTManager;Время#на#устройстве;10
5 0;output-value;weekday;anydata;IoTManager;День#недели#на#устройстве ;11

View File

@@ -1 +1,5 @@
//
timenow > 0
weekday %weekday%
ip %IP%
time %date%
end

View File

@@ -0,0 +1 @@
.letter.svelte-1ls9om6{color:grey;font-size:60%;padding-left:0px;opacity:0.5}table.svelte-1ls9om6{margin:0px;background-color:#fafafa;line-height:1}td.svelte-1ls9om6{text-align:left;padding-left:1px}input[type="text"].svelte-1ls9om6{width:100%;padding:10px;border:1;box-shadow:0 0 15px 10px rgba(0, 0, 0, 0.06);border-radius:1px}.letter1.svelte-1ls9om6{color:grey;font-size:80%;padding-left:20px}.letter2.svelte-1ls9om6{text-align:left;padding-left:0px}select.svelte-1ls9om6{padding:10px;border-radius:10px;padding-left:20px;height:40px;font-size:13px}input[type="password"].svelte-1ls9om6{width:100%;padding:10px;border:1;box-shadow:0 0 15px 10px rgba(0, 0, 0, 0.06);border-radius:1px}input.svelte-1ls9om6:required:invalid:not(:placeholder-shown){border-color:crimson}.red.svelte-1ls9om6{border-color:crimson}progress.svelte-1ls9om6{height:4px}textarea.svelte-1ls9om6{width:100%}button.svelte-1ls9om6{height:30px;border-radius:4px;line-height:0}body.light-mode{background-color:white}body.dark-mode{background-color:#1d3040;color:#bfc2c7}body.dark-mode textarea.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode input.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode select.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode button.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode div.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode span.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}.Shutter.svelte-1ls9om6{background-color:hsl(200, 16%, 96%);color:blak;padding:10px;border-radius:5px}body.dark-mode .Shutter.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7;padding:10px;border-radius:5px}body.dark-mode table.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}body.dark-mode .letter1.svelte-1ls9om6{color:#bfc2c7}body.dark-mode .letter2.svelte-1ls9om6{color:#bfc2c7}body.dark-mode b.svelte-1ls9om6{color:#bfc2c7}body.dark-mode button.svelte-1ls9om6{background-color:#1d3040;color:#bfc2c7}h5.svelte-1ls9om6{display:inline}.box.svelte-hp9es9{width:93%;border:1px solid #aaa;border-radius:10px;box-shadow:10px 10px 8px rgba(0, 0, 0, 0.1);padding:1em;margin:0 0 1em 0}.tooltip.svelte-1vepdvs{border:1px solid #ddd;box-shadow:1px 1px 1px #ddd;background:rgb(185, 238, 241);border-radius:4px;padding:4px;position:absolute;color:black}.modal-background.svelte-10j5cq5{position:fixed;top:0;left:0;width:100%;height:100%;background:gray;opacity:0.8}.modal.svelte-10j5cq5{position:absolute;left:50%;top:50%;width:calc(100vw - 4em);max-width:32em;max-height:calc(100vh - 4em);overflow:auto;transform:translate(-50%, -50%);padding:1em;border-radius:0.2em;background:white}button.svelte-10j5cq5{display:block}.rotate-shadows.svelte-tks6xu{width:220px;height:220px;position:relative}.rotate-shadows.svelte-tks6xu:after,.rotate-shadows.svelte-tks6xu:before{content:"";border-radius:150%;position:absolute;top:0;left:0;width:100%;height:100%;transform-origin:center center}.rotate-shadows.svelte-tks6xu:before{box-shadow:inset 0 20px 0 rgba(0, 250, 250, 0.2), inset 20px 0 0 rgba(0, 200, 200, 0.2), inset 0 -20px 0 rgba(0, 150, 200, 0.2), inset -20px 0 0 rgba(0, 200, 250, 0.2);animation:svelte-tks6xu-rotate-before 9s -0.5s linear infinite}.rotate-shadows.svelte-tks6xu:after{box-shadow:inset 0 20px 0 rgba(250, 250, 0, 0.2), inset 20px 0 0 rgba(250, 200, 0, 0.2), inset 0 -20px 0 rgba(250, 150, 0, 0.2), inset -20px 0 0 rgba(250, 100, 0, 0.2);animation:svelte-tks6xu-rotate-after 9s -0.5s linear infinite}@keyframes svelte-tks6xu-rotate-after{0%{transform:rotateZ(0deg) scaleX(1) scaleY(1)}50%{transform:rotateZ(180deg) scaleX(0.82) scaleY(0.95)}100%{transform:rotateZ(360deg) scaleX(1) scaleY(1)}}@keyframes svelte-tks6xu-rotate-before{0%{transform:rotateZ(0deg) scaleX(1) scaleY(1)}50%{transform:rotateZ(-180deg) scaleX(0.95) scaleY(0.85)}100%{transform:rotateZ(-360deg) scaleX(1) scaleY(1)}}

Binary file not shown.

63
data_ms/setup/global.css Normal file
View File

@@ -0,0 +1,63 @@
html, body {
position: relative;
width: 100%;
height: 100%;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
-webkit-padding: 0.4em 0;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}

103
data_ms/setup/index.html Normal file
View File

@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>IotManager v 0.3.2</title>
<link rel="icon" type="image/png" href="/favicon.ico" />
<link rel="stylesheet" href="/setup/global.css" />
<link rel="stylesheet" href="/setup/build/bundle.css?0.3" />
<script defer src="/setup/build/bundle.js?0.3" onload="loadPage()"></script>
<script>
function get_cookie ( cookie_name ){
var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)' );
if ( results )
return ( unescape ( results[2] ) );
else
return null;
}
if (get_cookie("darktheme") == "true"){
var myColor = "#1d3040";
document.write('\
<style>\
body{\
background-color: '+myColor+';\
}\
</style>\
');
}
function loadPage() {
document.getElementById("status").style.display = "none";
}
</script>
<style>
.rotate-shadows {
width: 220px;
height: 220px;
margin:0 auto;
position: relative;
}
.rotate-shadows:after,
.rotate-shadows:before {
content: "";
border-radius: 150%;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: center center;
}
.rotate-shadows:before {
box-shadow: inset 0 20px 0 rgba(0, 250, 250, 0.2),
inset 20px 0 0 rgba(0, 200, 200, 0.2),
inset 0 -20px 0 rgba(0, 150, 200, 0.2),
inset -20px 0 0 rgba(0, 200, 250, 0.2);
animation: rotate-before 9s -0.5s linear infinite;
}
.rotate-shadows:after {
box-shadow: inset 0 20px 0 rgba(250, 250, 0, 0.2),
inset 20px 0 0 rgba(250, 200, 0, 0.2),
inset 0 -20px 0 rgba(250, 150, 0, 0.2),
inset -20px 0 0 rgba(250, 100, 0, 0.2);
animation: rotate-after 9s -0.5s linear infinite;
}
@keyframes rotate-after {
0% {
transform: rotateZ(0deg) scaleX(1) scaleY(1);
}
50% {
transform: rotateZ(180deg) scaleX(0.82) scaleY(0.95);
}
100% {
transform: rotateZ(360deg) scaleX(1) scaleY(1);
}
}
@keyframes rotate-before {
0% {
transform: rotateZ(0deg) scaleX(1) scaleY(1);
}
50% {
transform: rotateZ(-180deg) scaleX(0.95) scaleY(0.85);
}
100% {
transform: rotateZ(-360deg) scaleX(1) scaleY(1);
}
}
</style>
</head>
<body>
<p><div id="status" class="rotate-shadows"></div></p>
</body>
</html>

BIN
data_ms/setup/progress.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -1,33 +1,35 @@
{
"toggleBtn": "Кнопка переключатель",
"range": "Ползунок",
"inputDate": "Окно ввода даты",
"inputTime": "Окно ввода времени 1",
"inputTimeClock": "Окно ввода времени 2",
"inputDigit": "Окно ввода цифры",
"inputDigitTemp": "Окно ввода температуры",
"inputText": "Окно ввода текста",
"select": "Выпадающий список",
"chart": "График без точек",
"chart2": "График с точками",
"chart3": "График дневного расхода (столбики)",
"chart4": "График дневного расхода (плавный)",
"fillgauge": "Бочка",
"progress-line": "Линия",
"progress-round": "Круг",
"anydata": "Текст",
"anydataHum": "Влажность (%)",
"anydataPress": "Давление (mm)",
"anydataTemp": "Температура (°С)",
"anydataPpb": "Части на миллиард (ppb)",
"anydataPpm": "Части на миллион (ppm)",
"anydataVlt": "Напряжение (Vlt)",
"anydataAmp": "Сила тока (Amp)",
"anydataWtt": "Мощность (Wtt)",
"anydataWhr": "Энергия (Whr)",
"anydataHtz": "Частота (Htz)",
"anydataTime": "Манометр",
"alarm": "Тревожное сообщение 1",
"anydataAlarm": "Тревожное сообщение 2",
"na": "Без виджета"
}
"undef": "Ошибка",
"toggleBtn": "Переключатель",
"btn": "Кнопка",
"select": "Кнопка переключатель",
"range": "Ползунок",
"inputDate": "Окно ввода даты",
"inputTime": "Окно ввода времени 1",
"inputTimeClock": "Окно ввода времени 2",
"inputDigit": "Окно ввода цифры",
"inputDigitTemp": "Окно ввода температуры",
"inputText": "Окно ввода текста",
"chart": "График без точек",
"chart2": "График с точками",
"chart3": "График дневного расхода (столбики)",
"chart4": "График дневного расхода (плавный)",
"fillgauge": "Бочка",
"progress-line": "Линия",
"progress-round": "Круг",
"anydata": "Текст",
"anydataHum": "Влажность (%)",
"anydataPress": "Давление (mm)",
"anydataTemp": "Температура (°С)",
"anydataPpb": "Части на миллиард (ppb)",
"anydataPpm": "Части на миллион (ppm)",
"anydataVlt": "Напряжение (Vlt)",
"anydataAmp": "Сила тока (Amp)",
"anydataWtt": "Мощность (Wtt)",
"anydataWhr": "Энергия (Whr)",
"anydataHtz": "Частота (Htz)",
"anydataTime": "Манометр",
"alarm": "Тревожное сообщение 1",
"anydataAlarm": "Тревожное сообщение 2",
"na": "Без виджета"
}

View File

@@ -1,5 +1,16 @@
{
"widget": "anydata",
"after": "°С",
"icon": "thermometer"
}
"icon": "thermometer",
"font": "OCR A Std",
"color": [
{ "level": -20, "value": "#0000CC" },
{ "level": -10, "value": "#0000CC" },
{ "level": 0, "value": "#0000CC" },
{ "level": 12, "value": "#3366FF" },
{ "level": 16, "value": "#33CCFF" },
{ "level": 18, "value": "#009933" },
{ "level": 30, "value": "#FF9900" },
{ "level": 40, "value": "red" }
]
}

View File

@@ -3,20 +3,20 @@
"chipID": "",
"apssid": "IoTmanager",
"appass": "",
"routerssid": "rise2",
"routerssid": "rise",
"routerpass": "hostel3333",
"timezone": 1,
"ntp": "pool.ntp.org",
"mqttServer": "91.204.228.124",
"mqttPort": 1883,
"mqttServer": "M2.WQTT.RU",
"mqttPort": 8021,
"mqttPrefix": "/iotTest3",
"mqttUser": "rise",
"mqttPass": "23ri22se32",
"mqttServer2": "M2.WQTT.RU",
"mqttPort2": 8021,
"mqttPrefix2": "/iotTest3",
"mqttUser2": "rise",
"mqttPass2": "hostel3333",
"mqttPass": "hostel3333",
"mqttServer2": "",
"mqttPort2": 0,
"mqttPrefix2": "",
"mqttUser2": "",
"mqttPass2": "",
"scen": "1",
"telegramApi": "1416711569:AAEI0j83GmXqwzb_gnK1B0Am0gDwZoJt5xo",
"telegonof": "0",
@@ -26,7 +26,7 @@
"webpass": "admin",
"MqttIn": "0",
"MqttOut": "0",
"blink": "0",
"blink": "1",
"oneWirePin": "2",
"serverip": "http://206.189.49.244",
"uart": "0",

View File

@@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x150000,
app1, app, ota_1, 0x160000,0x150000,
spiffs, data, spiffs, 0x2B0000,0x150000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x150000
5 app1 app ota_1 0x160000 0x150000
6 spiffs data spiffs 0x2B0000 0x150000

View File

@@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
app1, app, ota_1, 0x150000,0x140000,
spiffs, data, spiffs, 0x290000,0x170000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x140000
5 app1 app ota_1 0x150000 0x140000
6 spiffs data spiffs 0x290000 0x170000

21
include/Class/IoTModule.h Normal file
View File

@@ -0,0 +1,21 @@
#pragma once
#include <WString.h>
struct ModuleInfo
{
String name; //имя модуля
String title; //заголовок для описания модуля
String parameters; //параметры, которые может принять модуль и сущность
String type; //тип для определения сущности, которую генерирует модуль Sensor или Variable
};
class IoTModule {
public:
IoTModule();
~IoTModule();
virtual void* initInstance(String parameters);
virtual ModuleInfo getInfo();
virtual void clear();
};

26
include/Class/IoTSensor.h Normal file
View File

@@ -0,0 +1,26 @@
#pragma once
#include <WString.h>
class IoTSensor {
public:
IoTSensor();
~IoTSensor();
void loop();
virtual void doByInterval();
void init(String key, String id, unsigned long interval);
void regEvent(String value, String consoleInfo);
String getKey();
String getID();
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long difference;
protected:
String _key;
String _id;
unsigned long _interval;
};

View File

@@ -0,0 +1,27 @@
#pragma once
#include "Utils/JsonUtils.h"
#include <WString.h>
class IoTVariable {
public:
IoTVariable();
~IoTVariable();
virtual String execute(String command);
virtual void selfExec();
virtual void loop();
virtual String getValue(String key);
void init(String key, String id);
void regEvent(String value, String consoleInfo);
String loadValue(String id);
String getKey();
String getID();
protected:
String _key; //имя переменной, для идентификации при работе с несколькими переменными в одном модуле
String _id; //код переменной для идентификации событий, команд в сценариях и логах
};

View File

@@ -210,6 +210,9 @@ class LineParsing {
String gtm2() {
return _tm2;
}
String gdb() {
return _db;
}
int getPinErrors() {
return pinErrors;

View File

@@ -3,7 +3,7 @@
#include "Clock.h"
#include "Global.h"
#include "Utils/TimeUtils.h"
#include "Utils\SerialPrint.h"
#include "Utils/SerialPrint.h"
extern void clockInit();
@@ -143,8 +143,16 @@ class Clock {
return String(buf);
}
/*
* Локальное дата время "день недели"
*/
const String getWeekday() {
char buf[32];
sprintf(buf, "%d", _time_local.day_of_week);
return String(buf);
}
/*
/*
* Локальное время "чч:мм:cc"
*/
const String getTime() {

View File

@@ -1,6 +1,6 @@
#pragma once
#define FIRMWARE_VERSION 302
#define FIRMWARE_VERSION 304
//#define svelte
@@ -46,7 +46,13 @@
#define MYSENSORS
#endif
#ifndef esp32_4mb
#define NUM_BUTTONS 6
#endif
#ifdef esp32_4mb
#define NUM_BUTTONS 8
#endif
#define MQTT_RECONNECT_INTERVAL 20000
#define CHANGE_BROKER_AFTER 5
#define TELEMETRY_UPDATE_INTERVAL_MIN 60
@@ -54,7 +60,7 @@
#define DEVICE_SCENARIO_FILE "s.scen.txt"
//#define OTA_UPDATES_ENABLED
//#define MDNS_ENABLED
//#define WEBSOCKET_ENABLED
#define WEBSOCKET_ENABLED
//#define LAYOUT_IN_RAM
//#define UDP_ENABLED
//#define SSDP_ENABLED
@@ -70,6 +76,7 @@
#define EnablePwmOut
#define EnableSensorAnalog
#define EnableSensorBme280
#define EnableSensorSht20
#define EnableSensorBmp280
#define EnableSensorCcs811
#define EnableSensorDallas
@@ -77,6 +84,7 @@
#define EnableSensorPzem
#define EnableSensorUltrasonic
#define EnableSensorUptime
#define EnableSensorAny
#define EnableTelegram
#define EnableUart
#endif
@@ -132,27 +140,27 @@ enum ConfigType_t {
CT_SCENARIO
};
//history
//07.11.2020 (SSDP OFF, UDP OFF)
//RAM: [===== ] 46.8% (used 38376 bytes from 81920 bytes)
//Flash: [===== ] 54.2% (used 566004 bytes from 1044464 bytes)
// history
// 07.11.2020 (SSDP OFF, UDP OFF)
// RAM: [===== ] 46.8% (used 38376 bytes from 81920 bytes)
// Flash: [===== ] 54.2% (used 566004 bytes from 1044464 bytes)
//13.11.2020 (SSDP OFF, UDP OFF)
//RAM: [===== ] 46.6% (used 38208 bytes from 81920 bytes)
//Flash: [===== ] 54.2% (used 566388 bytes from 1044464 bytes)
// 13.11.2020 (SSDP OFF, UDP OFF)
// RAM: [===== ] 46.6% (used 38208 bytes from 81920 bytes)
// Flash: [===== ] 54.2% (used 566388 bytes from 1044464 bytes)
//15.11.2020 (SSDP OFF, UDP OFF)
//RAM: [===== ] 46.1% (used 37780 bytes from 81920 bytes)
//Flash: [===== ] 54.3% (used 566656 bytes from 1044464 bytes)
// 15.11.2020 (SSDP OFF, UDP OFF)
// RAM: [===== ] 46.1% (used 37780 bytes from 81920 bytes)
// Flash: [===== ] 54.3% (used 566656 bytes from 1044464 bytes)
//17.11.2020 (SSDP OFF, UDP OFF)
//RAM: [===== ] 45.7% (used 37476 bytes from 81920 bytes)
//Flash: [===== ] 54.5% (used 569296 bytes from 1044464 bytes)
// 17.11.2020 (SSDP OFF, UDP OFF)
// RAM: [===== ] 45.7% (used 37476 bytes from 81920 bytes)
// Flash: [===== ] 54.5% (used 569296 bytes from 1044464 bytes)
//RAM: [===== ] 45.6% (used 37336 bytes from 81920 bytes)
//Flash: [====== ] 55.3% (used 577396 bytes from 1044464 bytes)
// RAM: [===== ] 45.6% (used 37336 bytes from 81920 bytes)
// Flash: [====== ] 55.3% (used 577396 bytes from 1044464 bytes)
//eventBuf - буфер событий которые проверяются в сценариях,
// eventBuf - буфер событий которые проверяются в сценариях,
//и если событие удовлетворяет какому нибудь условию то выполняются указанные команды
//orderBuf - буфер команд которые выполняются сейчас же
// orderBuf - буфер команд которые выполняются сейчас же

View File

@@ -8,6 +8,8 @@ int jsonReadInt(String& json, String name);
boolean jsonReadBool(String& json, String name);
float jsonReadFloat(String& json, String name);
String jsonWriteStr(String& json, String name, String value);
String jsonWriteInt(String& json, String name, int value);

View File

@@ -2,6 +2,10 @@
#include <Arduino.h>
void hex2string(byte array[], unsigned int len, char buffer[]);
int string2hex(const char* str, unsigned char* bytes );
uint8_t hexStringToUint8(String hex);
uint16_t hexStringToUint16(String hex);

9
include/YourSensor.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
#include <Arduino.h>
float yourSensorReading(String type, String addr);
void HDC1080_init(String addr);
void AHTX0_init();
void LCD_init();
void BH1750_init();

View File

@@ -1,65 +0,0 @@
#ifdef EnableButtonIn
#pragma once
#include <Arduino.h>
#include <Bounce2.h>
#include "Class/LineParsing.h"
#include "Global.h"
extern boolean but[NUM_BUTTONS];
extern Bounce* buttons;
class ButtonInClass : public LineParsing {
protected:
int numberEntering = 0;
int state = _state.toInt();
public:
ButtonInClass() : LineParsing(){};
void init() {
if (_pin != "") {
int number = numberEntering++;
buttons[number].attach(_pin.toInt());
buttons[number].interval(_db.toInt());
but[number] = true;
jsonWriteStr(configOptionJson, "switch_num_" + String(number), _key);
}
}
void loop() {
static uint8_t switch_number = 1;
if (but[switch_number]) {
buttons[switch_number].update();
if (buttons[switch_number].fell()) {
String key = jsonReadStr(configOptionJson, "switch_num_" + String(switch_number));
state = 1;
switchChangeVirtual(key, String(state));
}
if (buttons[switch_number].rose()) {
String key = jsonReadStr(configOptionJson, "switch_num_" + String(switch_number));
state = 0;
switchChangeVirtual(key, String(state));
}
}
switch_number++;
if (switch_number == NUM_BUTTONS) {
switch_number = 0;
}
}
void switchStateSetDefault() {
if (_state != "") {
switchChangeVirtual(_key, _state);
}
}
void switchChangeVirtual(String key, String state) {
eventGen2(key, state);
jsonWriteInt(configLiveJson, key, state.toInt());
publishStatus(key, state);
}
};
extern ButtonInClass myButtonIn;
#endif

View File

@@ -1,30 +0,0 @@
#ifdef EnableButtonOut
#pragma once
#include <Arduino.h>
#include "Global.h"
class ButtonOut;
typedef std::vector<ButtonOut> MyButtonOutVector;
class ButtonOut {
public:
ButtonOut(String pin, boolean inv, String key, String type);
~ButtonOut();
void execute(String state);
private:
String _pin;
boolean _inv;
String _key;
String _type;
};
extern MyButtonOutVector* myButtonOut;
extern void buttonOut();
extern void buttonOutExecute();
#endif

View File

@@ -23,7 +23,6 @@ class ImpulsOutClass {
unsigned int _impulsCount = 0;
unsigned int _impulsCountBuf = 0;
unsigned int _impulsPin = 0;
};
extern MyImpulsOutVector* myImpulsOut;

View File

@@ -11,15 +11,11 @@ typedef std::vector<LoggingClass> MyLoggingVector;
class LoggingClass {
public:
LoggingClass(String interval, unsigned int maxPoints, String loggingValueKey, String key, String startState, bool savedFromWeb);
~LoggingClass();
void loop();
void execute(String keyOrValue);
private:
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long difference;
@@ -29,16 +25,14 @@ class LoggingClass {
unsigned int _maxPoints;
String _loggingValueKey;
String _key;
};
extern MyLoggingVector* myLogging;
extern void logging();
extern void loggingExecute();
extern void choose_log_date_and_send();
extern void choose_log_date_and_sendWS();
extern void sendLogData(String file, String topic);
extern void sendLogDataWS(String file, String topic);
extern void sendLogData2(String file, String topic);
extern void cleanLogAndData();
#endif

View File

@@ -1,29 +1,19 @@
#ifdef EnableOutput
#pragma once
#include <Arduino.h>
#include "Global.h"
class Output;
typedef std::vector<Output> MyOutputVector;
class Output {
public:
Output(String key);
~Output();
void execute(String value);
private:
String _key;
};
extern MyOutputVector* myOutput;
extern void outputValue();
extern void outputExecute();
#endif

View File

@@ -0,0 +1,37 @@
#ifdef EnableSensorAny
#pragma once
#include <Arduino.h>
#include "Global.h"
class SensorAny;
typedef std::vector<SensorAny> MySensorAnyVector;
class SensorAny {
public:
SensorAny(const String& paramsAny);
~SensorAny();
void loop();
void read();
private:
String _paramsAny;
int _interval;
float _c;
float _k;
String _key;
String _addr;
String _type;
String _val;
String _descr;
unsigned long prevMillis;
unsigned long difference;
};
extern MySensorAnyVector* mySensorAny;
extern void AnySensor();
#endif

View File

@@ -1,37 +0,0 @@
#ifdef EnableSensorDallas
#pragma once
#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Global.h"
extern DallasTemperature sensors;
extern OneWire* oneWire;
class SensorDallas;
typedef std::vector<SensorDallas> MySensorDallasVector;
class SensorDallas {
public:
SensorDallas(unsigned long interval, unsigned int pin, unsigned int index, String key);
~SensorDallas();
void loop();
void readDallas();
private:
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long difference;
unsigned long _interval;
String _key;
unsigned int _pin;
unsigned int _index;
};
extern MySensorDallasVector* mySensorDallas2;
extern void dallas();
#endif

BIN
partitions.xlsx Normal file

Binary file not shown.

View File

@@ -1,6 +0,0 @@
# Name, Type, SubType, Offset, Size, Flags
ota_0, app, ota_0, 0x10000, 0x1A0000
ota_1, app, ota_1, , 0x1A0000
otadata, data, ota, 0x350000, 0x2000
nvs, data, nvs, , 0x6000
data, data, spiffs, , 0xA8000
1 # Name, Type, SubType, Offset, Size, Flags
2 ota_0, app, ota_0, 0x10000, 0x1A0000
3 ota_1, app, ota_1, , 0x1A0000
4 otadata, data, ota, 0x350000, 0x2000
5 nvs, data, nvs, , 0x6000
6 data, data, spiffs, , 0xA8000

View File

@@ -8,34 +8,20 @@
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
;==============================================================================================
;To choose firmware please use one of definition:
;esp8266_1mb , esp8266_4mb , esp32_4mb , esp8266_mysensors_4mb , esp32_mysensors_4mb
[platformio]
default_envs = esp32_4mb
;data_esp => esp8266_1mb , esp8266_4mb , esp32_4mb
;data_ms => esp8266_mysensors_4mb , esp32_mysensors_4mb
;data_svelte => new web interface (in progress...)
data_dir = data_esp
;==============================================================================================
[common_env_data]
lib_deps_external =
bblanchon/ArduinoJson @5.*
knolleary/PubSubClient
lib_deps_internal =
ESP Async WebServer
GyverFilters
OneWire
EspSoftwareSerial
[env:esp8266_4mb]
build_flags = -Desp8266_4mb="esp8266_4mb"
framework = arduino
@@ -54,12 +40,16 @@ lib_deps =
adafruit/Adafruit BME280 Library
adafruit/Adafruit CCS811 Library
milesburton/DallasTemperature
robtillaart/SHT2x@^0.1.1
ClosedCube HDC1080
Adafruit AHTX0
LiquidCrystal_I2C
BH1750
monitor_filters = esp8266_exception_decoder
upload_speed = 921600
monitor_speed = 115200
board_build.filesystem = littlefs
[env:esp8266_1mb]
build_flags = -Desp8266_1mb="esp8266_1mb"
framework = arduino
@@ -78,11 +68,15 @@ lib_deps =
adafruit/Adafruit BME280 Library
adafruit/Adafruit CCS811 Library
milesburton/DallasTemperature
robtillaart/SHT2x@^0.1.1
ClosedCube HDC1080
Adafruit AHTX0
LiquidCrystal_I2C
BH1750
monitor_filters = esp8266_exception_decoder
upload_speed = 921600
monitor_speed = 115200
[env:esp8266_mysensors_4mb]
build_flags = -Desp8266_mysensors_4mb="esp8266_mysensors_4mb"
framework = arduino
@@ -101,12 +95,11 @@ upload_speed = 921600
monitor_speed = 115200
board_build.filesystem = littlefs
[env:esp32_4mb]
build_flags = -Desp32_4mb="esp32_4mb"
framework = arduino
board = esp32dev
platform = espressif32 @3.3.0
platform = espressif32 @3.4.0
lib_deps =
${common_env_data.lib_deps_external}
${common_env_data.lib_deps_internal}
@@ -121,16 +114,21 @@ lib_deps =
adafruit/Adafruit BME280 Library
adafruit/Adafruit CCS811 Library
milesburton/DallasTemperature
robtillaart/SHT2x@^0.1.1
ClosedCube HDC1080
Adafruit AHTX0
LiquidCrystal_I2C
BH1750
monitor_filters = esp32_exception_decoder
upload_speed = 921600
monitor_speed = 115200
board_build.partitions = esp32_partitions_castom.csv
[env:esp32_mysensors_4mb]
build_flags = -Desp32_mysensors_4mb="esp32_mysensors_4mb"
framework = arduino
board = esp32dev
platform = espressif32 @3.3.0
platform = espressif32 @3.3.0
lib_deps =
${common_env_data.lib_deps_external}
${common_env_data.lib_deps_internal}
@@ -142,4 +140,4 @@ lib_deps =
MySensors @2.3.2
monitor_filters = esp32_exception_decoder
upload_speed = 921600
monitor_speed = 115200
monitor_speed = 115200

View File

@@ -3,7 +3,6 @@
#include "Global.h"
#include "SoftUART.h"
#include "items/test.h"
#include "items/vButtonOut.h"
#include "items/vCountDown.h"
#include "items/vImpulsOut.h"
#include "items/vInput.h"
@@ -11,16 +10,27 @@
#include "items/vOutput.h"
#include "items/vPwmOut.h"
#include "items/vSensorAnalog.h"
#include "items/vSensorAny.h"
#include "items/vSensorBme280.h"
#include "items/vSensorBmp280.h"
#include "items/vSensorCcs811.h"
#include "items/vSensorDallas.h"
#include "items/vSensorDht.h"
#include "items/vSensorNode.h"
#include "items/vSensorPzem.h"
#include "items/vSensorUltrasonic.h"
#include "items/vSensorUptime.h"
#include "Class/LineParsing.h"
#include "Utils/JsonUtils.h"
#include "Class/IoTModule.h"
#include "Class/IoTSensor.h"
#include "Class/IoTVariable.h"
extern std::vector<IoTModule*> iotModules; //v3dev: вектор ссылок базового класса IoTModule - интерфейсы для общения со всеми поддерживаемыми системой модулями
extern std::vector<IoTSensor*> iotSensors; //v3dev: вектор ссылок базового класса IoTSensor - список всех запущенных сенсоров
extern std::vector<IoTVariable*> iotVariables; //v3dev: вектор ссылок базового класса IoTVariable - список всех подготовленных переменных
void loopCmdAdd(const String& cmdStr) {
if (cmdStr.endsWith(",")) {
orderBuf += cmdStr;
@@ -43,7 +53,7 @@ void loopCmdExecute() {
String tmp = selectToMarker(orderBuf, ","); //выделяем первую команду rel 5 1,
sCmd.readStr(tmp); //выполняем
if (tmp != "") {
sCmd.readStr(tmp);
sCmd.readStr(tmp);
SerialPrint("I", F("Order done L"), tmp);
}
orderBuf = deleteBeforeDelimiter(orderBuf, ","); //осекаем
@@ -69,19 +79,12 @@ void csvCmdExecute(String& cmdStr) {
count++;
if (count > 1) {
//SerialPrint("I", "Items", buf);
// SerialPrint("I", "Items", buf);
String order = selectToMarker(buf, " "); //отсечка самой команды
if (order == F("button-out")) {
#ifdef EnableButtonOut
sCmd.addCommand(order.c_str(), buttonOut);
#endif
} else if (order == F("pwm-out")) {
if (order == F("pwm-out")) {
#ifdef EnablePwmOut
sCmd.addCommand(order.c_str(), pwmOut);
#endif
} else if (order == F("button-in")) {
#ifdef EnableButtonIn
sCmd.addCommand(order.c_str(), buttonIn);
#endif
} else if (order == F("input-value")) {
#ifdef EnableInput
@@ -99,10 +102,11 @@ void csvCmdExecute(String& cmdStr) {
#ifdef EnableSensorUltrasonic
sCmd.addCommand(order.c_str(), ultrasonic);
#endif
//ИНТЕГРИРУЮ: Первая интеграция в ядро. Следим за наименованием
} else if (order == F("dallas-temp")) {
#ifdef EnableSensorDallas
sCmd.addCommand(order.c_str(), dallas);
#endif
// #ifdef EnableSensorDallas
// sCmd.addCommand(order.c_str(), dallas);
// #endif
} else if (order == F("dht")) {
#ifdef EnableSensorDht
sCmd.addCommand(order.c_str(), dhtSensor);
@@ -110,6 +114,10 @@ void csvCmdExecute(String& cmdStr) {
} else if (order == F("bme280")) {
#ifdef EnableSensorBme280
sCmd.addCommand(order.c_str(), bme280Sensor);
#endif
} else if (order == F("sensor")) {
#ifdef EnableSensorAny
sCmd.addCommand(order.c_str(), AnySensor);
#endif
} else if (order == F("bmp280")) {
#ifdef EnableSensorBmp280
@@ -141,7 +149,7 @@ void csvCmdExecute(String& cmdStr) {
#endif
} else if (order == F("impuls-in")) {
#ifdef EnableImpulsIn
//sCmd.addCommand(order.c_str(), impulsInSensor);
// sCmd.addCommand(order.c_str(), impulsInSensor);
#endif
} else if (order == F("sensor-node")) {
#ifdef EnableSensorNode
@@ -150,6 +158,34 @@ void csvCmdExecute(String& cmdStr) {
}
sCmd.readStr(buf);
//v3dev: инициируем экземпляр модулей в случае необходимости
for (unsigned int i = 0; i < iotModules.size(); i++) {
ModuleInfo moduleInfo = iotModules[i]->getInfo();
//del SerialPrint("I", "moduleInfo.name", moduleInfo.name);
//del SerialPrint("I", "order", order);
if (moduleInfo.name == order) { //проверка вхождения имени искомого модуля в ключе элемента настройки
myLineParsing.update(); //v3dev: пока используем мостик для совместимости версий, предполагается, что настройки сразу будут в JSON
String interval = myLineParsing.gint();
if (interval == "") interval = "50";
String pin = myLineParsing.gpin();
String index = myLineParsing.gindex();
String addr = myLineParsing.gaddr();
String c = myLineParsing.gc();
String id = myLineParsing.gkey();
String key = myLineParsing.gfile();
String db = myLineParsing.gdb();
myLineParsing.clear();
String strTmp = "{\"key\": \"" + key + "\", \"id\": \"" + id + "\", \"addr\": \"" + addr + "\", \"int\": \"" + interval + "\", \"pin\": \"" + pin + "\", \"index\": \"" + index + "\", \"c\": \"" + c + "\", \"db\": \"" + db + "\"}";
SerialPrint("I", "Строка параметров при инициализации модуля " + moduleInfo.name + ": ", strTmp);
if (moduleInfo.type == "Sensor") {
iotSensors.push_back((IoTSensor*)iotModules[i]->initInstance(strTmp));
} else if (moduleInfo.type == "Variable") {
iotVariables.push_back((IoTVariable*)iotModules[i]->initInstance(strTmp));
}
}
}
}
cmdStr = deleteBeforeDelimiter(cmdStr, "\n");
}

7
src/Class/IoTModule.cpp Normal file
View File

@@ -0,0 +1,7 @@
#include "Class/IoTModule.h"
IoTModule::IoTModule() {};
IoTModule::~IoTModule() {};
void* IoTModule::initInstance(String parameters) {};
ModuleInfo IoTModule::getInfo() {};
void IoTModule::clear() {};

39
src/Class/IoTSensor.cpp Normal file
View File

@@ -0,0 +1,39 @@
#include "Utils/JsonUtils.h"
#include "Utils/SerialPrint.h"
#include "Class/ScenarioClass3.h"
#include "Class/IoTSensor.h"
void IoTSensor::init(String key, String id, unsigned long interval) {
_interval = interval * 1000;
_key = key;
_id = id;
}
IoTSensor::IoTSensor() {}
IoTSensor::~IoTSensor() {}
String IoTSensor::getKey() {
return _key;
}
String IoTSensor::getID() {
return _id;
};
void IoTSensor::loop() {
currentMillis = millis();
difference = currentMillis - prevMillis;
if (difference >= _interval) {
prevMillis = millis();
this->doByInterval();
}
}
void IoTSensor::regEvent(String value, String consoleInfo = "") {
eventGen2(_id, String(value));
jsonWriteStr(configLiveJson, _id, String(value));
publishStatus(_id, String(value));
SerialPrint("I", "Sensor", "'" + _id + "' data: " + String(value) + "' " + consoleInfo);
}
void IoTSensor::doByInterval() {}

36
src/Class/IoTVariable.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include "Utils/JsonUtils.h"
#include "Utils/SerialPrint.h"
#include "Class/ScenarioClass3.h"
#include "Class/IoTVariable.h"
IoTVariable::IoTVariable() {}
IoTVariable::~IoTVariable() {}
String IoTVariable::execute(String command) { return "";}
void IoTVariable::selfExec() {}
void IoTVariable::loop() {}
String IoTVariable::getValue(String key) { return "";}
void IoTVariable::init(String key, String id) {
_key = key;
_id = id;
}
void IoTVariable::regEvent(String value, String consoleInfo = "") {
eventGen2(_id, String(value));
jsonWriteStr(configLiveJson, _id, String(value));
publishStatus(_id, String(value));
SerialPrint("I", "Variable", "'" + _id + "' data: " + String(value) + "' " + consoleInfo);
}
String IoTVariable::getKey() {
return _key;
}
String IoTVariable::getID() {
return _id;
};
String IoTVariable::loadValue(String id) {
return jsonReadStr(configStoreJson, id); //прочитали из памяти
};

View File

@@ -184,21 +184,22 @@ void FSEditor::getDirList(const String &path, String &output) {
}
#else
void FSEditor::getDirList(const String &path, String &output) {
auto dir = _fs.open(path, FILE_READ);
File dir = _fs.open(path.c_str(), FILE_READ);
dir.rewindDirectory();
while (dir.openNextFile()) {
String fname = dir.name();
if (!path.endsWith("/") && !fname.startsWith("/")) {
fname = "/" + fname;
}
fname = path + fname;
if (isExcluded(_fs, fname.c_str())) {
continue;
}
if (dir.isDirectory()) {
getDirList(fname, output);
continue;
}
File file;
while (file = dir.openNextFile()) {
String fname = file.name();
//if (!path.endsWith("/") && !fname.startsWith("/")) {
// fname = "/" + fname;
//}
//fname = path + fname;
//if (isExcluded(_fs, fname.c_str())) {
// continue;
//}
//if (dir.isDirectory()) {
// getDirList(fname, output);
// continue;
//}
if (output != "[") output += ',';
char buf[128];
sprintf(buf, "{\"type\":\"file\",\"name\":\"%s\",\"size\":%d}", fname.c_str(), dir.size());

View File

@@ -4,7 +4,6 @@
#include "Class/LineParsing.h"
#include "Cmd.h"
#include "Global.h"
#include "items/vButtonOut.h"
#include "items/vCountDown.h"
#include "items/vImpulsOut.h"
#include "items/vInput.h"
@@ -15,13 +14,19 @@
#include "items/vSensorBme280.h"
#include "items/vSensorBmp280.h"
#include "items/vSensorCcs811.h"
#include "items/vSensorDallas.h"
#include "items/vSensorDht.h"
#include "items/vSensorNode.h"
#include "items/vSensorPzem.h"
#include "items/vSensorUltrasonic.h"
#include "items/vSensorUptime.h"
#include <vector>
#include "Class/IoTSensor.h"
#include "Class/IoTModule.h"
extern std::vector<IoTModule*> iotModules; //v3dev: вектор ссылок базового класса IoTModule - интерфейсы для общения со всеми поддерживаемыми системой модулями
extern std::vector<IoTSensor*> iotSensors; //v3dev: вектор ссылок базового класса IoTSensor - список всех запущенных сенсоров
void loadConfig() {
configSetupJson = readFile("config.json", 4096);
configSetupJson.replace("\r\n", "");
@@ -69,14 +74,14 @@ void deviceInit() {
int errors = myLineParsing.getPinErrors();
if (errors > 0) {
jsonWriteStr(configSetupJson, F("warning3"), F("<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #ffc7c7; padding: 10px;'>Обнаружен неверный номер пина</p></font></div>"));
jsonWriteStr(configSetupJson, F("warning3"), F("Обнаружен неверный номер пина"));
} else {
jsonWriteStr(configSetupJson, F("warning3"), "");
}
savedFromWeb = false;
//publishWidgets();
//publishState();
// publishWidgets();
// publishState();
}
void loadScenario() {
@@ -110,6 +115,21 @@ void handle_uptime() {
}
void clearVectors() {
//v3dev: очищаем вектора с сенсорами...
for (unsigned int i = 0; i < iotSensors.size(); i++) {
IoTSensor* tmpptr = iotSensors[i]; //временно сохраняем указатель на сенсор, т.к. его преждевременное удаление оставит поломаную запись в векторе, к которой может обратиться ядро и вызвать исключение
iotSensors.erase(iotSensors.begin() + i); //сначала удаляем элемент вектора,
delete tmpptr; //а далее уже удаляем объект сенсора
}
//...и переменными
//...
//заставляем модули прибраться за собой
for (unsigned int i = 0; i < iotModules.size(); i++) {
iotModules[i]->clear();
}
#ifdef EnableLogging
if (myLogging != nullptr) {
myLogging->clear();
@@ -133,13 +153,6 @@ void clearVectors() {
countDown_EnterCounter = -1;
#endif
#ifdef EnableButtonOut
if (myButtonOut != nullptr) {
myButtonOut->clear();
}
buttonOut_KeyList = "";
buttonOut_EnterCounter = -1;
#endif
#ifdef EnableInput
if (myInput != nullptr) {
myInput->clear();
@@ -160,12 +173,6 @@ void clearVectors() {
}
pwmOut_KeyList = "";
pwmOut_EnterCounter = -1;
#endif
//==================================
#ifdef EnableSensorDallas
if (mySensorDallas2 != nullptr) {
mySensorDallas2->clear();
}
#endif
#ifdef EnableSensorUltrasonic
if (mySensorUltrasonic != nullptr) {

View File

@@ -0,0 +1,79 @@
#include "Utils/JsonUtils.h"
#include "Utils/SerialPrint.h"
#include "Utils/StringUtils.h"
#include "Class/IoTSensor.h"
#include "Class/IoTModule.h"
#include <Bounce2.h>
class IoTSensorButtonIn: public IoTSensor {
private:
//описание переменных экземпляра датчика - аналог глобальных переменных из Arduino
//для работы библиотеки с несколькими линиями необходимо обеспечить каждый экземпляр класса ссылками на объекты настроенные на эти линии
Bounce* bButton;
boolean status;
//описание параметров передаваемых из настроек датчика из веба
unsigned int _pin;
unsigned int _db;
public:
//аналог setup() из Arduino
IoTSensorButtonIn(String parameters) {
//передаем часть базовых параметров в конструктор базового класса для обеспечения работы его методов
init(jsonReadStr(parameters, "key"), jsonReadStr(parameters, "id"), 0);
_pin = jsonReadInt(parameters, "pin");
_db = jsonReadInt(parameters, "db");
bButton = new Bounce();
bButton->attach(_pin, INPUT);
bButton->interval(_db);
status = true;
}
~IoTSensorButtonIn() {
delete bButton;
}
//аналог loop() из Arduino, но квотируемый по времени параметром interval
void doByInterval() {
bButton->update();
if (bButton->fell()) {
status = 1;
regEvent((String)status, ""); //обязательный вызов для отправки результата работы
}
if (bButton->rose()) {
status = 0;
regEvent((String)status, ""); //обязательный вызов для отправки результата работы
}
}
};
//технический класс для взаимодействия с ядром, меняются только названия
class IoTModuleButtonIn: public IoTModule {
//обязательный метод для инициализации экземпляра датчика, вызывается при чтении конфигурации. Нужно учитывать, что некоторые датчики могут обеспечивать
//несколько измерений, для каждого будет отдельный вызов.
void* initInstance(String parameters) {
return new IoTSensorButtonIn(parameters);
};
//обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память.
void clear() {
//и так чисто
}
//обязательный метод для отправки информации о модуле,
ModuleInfo getInfo() {
ModuleInfo MI;
MI.name = "button-in";
MI.title = "Кнопка физическая, чтение состояния пина (подключается проводами к устройству)";
MI.parameters = "{\"key\": \"button-in\", \"id\": \"btn\", \"pin\": \"2\", \"db\": \"20\"}";
MI.type = "Sensor";
return MI;
};
};
//точка входа в модуль для заполнения вектора, требуется только изменить имя и прописать в файле api.cpp
void* getApiIoTSensorButtonIn() {
return new IoTModuleButtonIn();
}

View File

@@ -0,0 +1,117 @@
#include "Utils/JsonUtils.h"
#include "Utils/SerialPrint.h"
#include "Utils/StringUtils.h"
#include "Class/IoTSensor.h"
#include "Class/IoTModule.h"
#include "DallasTemperature.h"
#include <OneWire.h>
#include <map>
//глобальные списки необходимы для хранения объектов об активных линиях 1-wire используемых разными датчиками из модуля. Ключ - номер пина
std::map<int, OneWire*> oneWireTemperatureArray;
std::map<int, DallasTemperature*> sensorsTemperatureArray;
class IoTSensorDallas: public IoTSensor {
private:
//описание переменных экземпляра датчика - аналог глобальных переменных из Arduino
//для работы библиотеки с несколькими линиями необходимо обеспечить каждый экземпляр класса ссылками на объекты настроенные на эти линии
OneWire* oneWire;
DallasTemperature* sensors;
//описание параметров передаваемых из настроек датчика из веба
String _addr;
unsigned int _pin;
unsigned int _index;
public:
//аналог setup() из Arduino
IoTSensorDallas(String parameters) {
//передаем часть базовых параметров в конструктор базового класса для обеспечения работы его методов
init(jsonReadStr(parameters, "key"), jsonReadStr(parameters, "id"), jsonReadInt(parameters, "int"));
_pin = jsonReadInt(parameters, "pin");
_index = jsonReadInt(parameters, "index");
_addr = jsonReadStr(parameters, "addr");
//учитываем, что библиотека может работать с несколькими линиями на разных пинах, поэтому инициируем библиотеку, если линия ранее не использовалась
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];
}
}
~IoTSensorDallas() {}
//аналог loop() из Arduino но квотируемый по времени параметром interval
void doByInterval() {
//запускаем опрос измерений у всех датчиков на линии
sensors->requestTemperatures();
//Определяем адрес. Если парамтер addr не установлен, то узнаем адрес по индексу
DeviceAddress deviceAddress;
if (_addr == "") {
sensors->getAddress(deviceAddress, _index);
} else {
string2hex(_addr.c_str(), deviceAddress);
}
//получаем температуру по адресу
float value = sensors->getTempC(deviceAddress);
char addrStr[20] = "";
hex2string(deviceAddress, 8, addrStr);
regEvent((String)value, "addr: " + String(addrStr)); //обязательный вызов для отправки результата работы
}
};
//технический класс для взаимодействия с ядром, меняются только названия
class IoTModuleDallasTemp: public IoTModule {
//обязательный метод для инициализации экземпляра датчика, вызывается при чтении конфигурации. Нужно учитывать, что некоторые датчики могут обеспечивать
//несколько измерений, для каждого будет отдельный вызов.
void* initInstance(String parameters) {
return new IoTSensorDallas(parameters);
};
//обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память.
void clear() {
// for (auto it = sensorsTemperatureArray.cbegin(), next_it = it; it != sensorsTemperatureArray.cend(); it = next_it) {
// ++next_it;
// DallasTemperature* tmpptr = it->second; //временно сохраняем указатель на сенсор, т.к. его преждевременное удаление оставит поломаную запись в векторе, к которой может обратиться ядро и вызвать исключение
// sensorsTemperatureArray.erase(it);
// delete tmpptr; //а далее уже удаляем объект сенсора
// }
// for (auto it = oneWireTemperatureArray.cbegin(), next_it = it; it != oneWireTemperatureArray.cend(); it = next_it) {
// ++next_it;
// OneWire* tmpptr = it->second; //временно сохраняем указатель на сенсор, т.к. его преждевременное удаление оставит поломаную запись в векторе, к которой может обратиться ядро и вызвать исключение
// oneWireTemperatureArray.erase(it);
// delete tmpptr; //а далее уже удаляем объект сенсора
// }
}
//обязательный метод для отправки информации о модуле,
ModuleInfo getInfo() {
ModuleInfo MI;
MI.name = "dallas-temp";
MI.title = "Датчик температуры Ds18b20";
MI.parameters = "{\"key\": \"dallas-temp\", \"id\": \"tmp\", \"addr\": \"\", \"int\": \"10\", \"pin\": \"18\", \"index\": \"0\"}";
MI.type = "Sensor";
return MI;
};
};
//точка входа в модуль для заполнения вектора, требуется только изменить имя и прописать в файле api.cpp
void* getApiIoTSensorDallasTemp() {
return new IoTModuleDallasTemp();
}

View File

@@ -0,0 +1,80 @@
#include "Utils/JsonUtils.h"
#include "Utils/SerialPrint.h"
#include "Utils/StringUtils.h"
#include "Class/IoTSensor.h"
#include "Class/IoTModule.h"
#include "Wire.h"
#include "SHT2x.h"
SHT2x* sht = nullptr;
class IoTSensorSHT20: public IoTSensor {
private:
//описание переменных экземпляра датчика - аналог глобальных переменных из Arduino
//описание параметров передаваемых из настроек датчика из веба
float _c;
public:
//аналог setup() из Arduino
IoTSensorSHT20(String parameters) {
//передаем часть базовых параметров в конструктор базового класса для обеспечения работы его методов
init(jsonReadStr(parameters, "key"), jsonReadStr(parameters, "id"), jsonReadInt(parameters, "int"));
_c = jsonReadFloat(parameters, "c");
if (!sht) {
sht = new SHT2x;
sht->begin();
}
}
~IoTSensorSHT20() {}
//аналог loop() из Arduino но квотируемый по времени параметром interval
void doByInterval() {
//запускаем опрос измерений
sht->read();
float value;
if (getKey() == "anydataTemp") {
value = sht->getTemperature();
} else {
value = sht->getHumidity();
}
value = _c * value;
regEvent((String)value, ""); //обязательный вызов для отправки результата измерений
}
};
//технический класс для взаимодействия с ядром, меняются только названия
class IoTModuleSHT20: public IoTModule {
//обязательный метод для инициализации экземпляра датчика, вызывается при чтении конфигурации. Нужно учитывать, что некоторые датчики могут обеспечивать
//несколько измерений, для каждого будет отдельный вызов.
void* initInstance(String parameters) {
return new IoTSensorSHT20(parameters);
};
//обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память.
void clear() {
}
//обязательный метод для отправки информации о модуле,
ModuleInfo getInfo() {
ModuleInfo MI;
MI.name = "sht20";
MI.title = "Датчик температуры и влажности SHT2x, HTU2x and Si70xx";
//v3dev: key - это внутренний маркер-ключ определяющий значение для измерений, на этапе апробации на ver3 установлено значение = типу виджета, т.к. в таблице настройки отсутствует парамтер key в этой интерпретации
MI.parameters = "{\"key\": \"anydataTemp\", \"id\": \"SHT20\", \"int\": \"10\", \"c\": \"1\"}, {\"key\": \"anydataHum\", \"id\": \"SHT20\", \"int\": \"10\", \"c\": \"1\"}";
MI.type = "Sensor";
return MI;
};
};
//точка входа в модуль для заполнения вектора, требуется только изменить имя и прописать в файле api.cpp
void* getApiIoTSensorSHT20() {
return new IoTModuleSHT20();
}

View File

@@ -0,0 +1,98 @@
#include "Utils/JsonUtils.h"
#include "Utils/SerialPrint.h"
#include "Utils/StringUtils.h"
#include "Class/IoTVariable.h"
#include "Class/IoTModule.h"
class IoTVariableButtonOut: public IoTVariable {
private:
//описание переменных экземпляра Variable - аналог глобальных переменных из Arduino
bool _state;
//описание параметров передаваемых из настроек переменной из веба
bool _isInvert;
int _pin;
public:
//аналог setup() из Arduino
IoTVariableButtonOut(String parameters) {
//передаем часть базовых параметров в конструктор базового класса для обеспечения работы его методов
init(jsonReadStr(parameters, "key"), jsonReadStr(parameters, "id"));
_pin = jsonReadBool(parameters, "pin");
_isInvert = jsonReadBool(parameters, "inv");
_state = this->loadValue(_id); //прочитали из памяти
if (_pin) {
pinMode(_pin, OUTPUT);
this->execute(String(_state)); //установили это состояние
}
}
~IoTVariableButtonOut() {}
//аналог loop() из Arduino
void loop() {
}
//вызывается при выполнении команды связанной с конкретным экземпляром переменной, передаем команду целиком после идентификатора в сценарии (минус пробел)
String execute(String command) {
if (command != "" && _pin > 0) {
if (command == "change") {
_state = !digitalRead(_pin);
digitalWrite(_pin, _state);
} else {
int newState = command.toInt();
if (_isInvert) {
digitalWrite(_pin, !newState);
} else {
digitalWrite(_pin, newState);
}
}
selfExec();
regEvent((String)_state, "");
}
return "";
}
//EXPEREMENTAL.вызывается при любом изменении переменной (задумка для реализации возможности вызова своего кода при клике на кнопку в веб-интерфейсе.
//Создаем модуль с реализацией и выбираем в конфигурации нужный виджет с кнопкой) для других реализаций
void selfExec() {
}
String getValue(String key) {
return (String)_state;
}
};
//технический класс для взаимодействия с ядром, меняются только названия
class IoTModuleButtonOut: public IoTModule {
//обязательный метод для инициализации экземпляра переменной, вызывается при чтении конфигурации.
void* initInstance(String parameters) {
return new IoTVariableButtonOut(parameters);
};
//обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память.
void clear() {
//и так чисто
}
//обязательный метод для отправки информации о модуле,
ModuleInfo getInfo() {
ModuleInfo MI;
MI.name = "button-out";
MI.title = "Кнопка управляющая пином";
MI.parameters = "{\"key\": \"button-out\", \"id\": \"var\", \"pin\": \"2\", \"inv\": \"0\"}";
MI.type = "Variable";
return MI;
};
};
//точка входа в модуль для заполнения вектора, требуется только изменить имя и прописать в файле api.cpp
void* getApiIoTVariableButtonOut() {
return new IoTModuleButtonOut();
}

View File

@@ -0,0 +1,73 @@
#include "Utils/JsonUtils.h"
#include "Utils/SerialPrint.h"
#include "Utils/StringUtils.h"
#include "Class/IoTVariable.h"
#include "Class/IoTModule.h"
class IoTVariableVirtual: public IoTVariable {
private:
//описание переменных экземпляра Variable - аналог глобальных переменных из Arduino
String _value;
//описание параметров передаваемых из настроек переменной из веба
public:
//аналог setup() из Arduino
IoTVariableVirtual(String parameters) {
//передаем часть базовых параметров в конструктор базового класса для обеспечения работы его методов
init(jsonReadStr(parameters, "key"), jsonReadStr(parameters, "id"));
}
~IoTVariableVirtual() {}
//аналог loop() из Arduino
void loop() {
}
//вызывается при выполнении команды связанной с конкретным экземпляром переменной
String execute(String command) {
return "";
}
//вызывается при любом изменении переменной
void selfExec() {
}
String getValue(String key="") {
return _value;
}
};
//технический класс для взаимодействия с ядром, меняются только названия
class IoTModuleVariable: public IoTModule {
//обязательный метод для инициализации экземпляра переменной, вызывается при чтении конфигурации.
void* initInstance(String parameters) {
return new IoTVariableVirtual(parameters);
};
//обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память.
void clear() {
//и так чисто
}
//обязательный метод для отправки информации о модуле,
ModuleInfo getInfo() {
ModuleInfo MI;
MI.name = "variable";
MI.title = "Переменная для хранения значений пользователя";
MI.parameters = "{\"key\": \"variable\", \"id\": \"var\"}";
MI.type = "Variable";
return MI;
};
};
//точка входа в модуль для заполнения вектора, требуется только изменить имя и прописать в файле api.cpp
void* getApiIoTVariableVirtual() {
return new IoTModuleVariable();
}

25
src/Modules/api.cpp Normal file
View File

@@ -0,0 +1,25 @@
#include "Utils/SerialPrint.h"
#include "Class/IoTSensor.h"
#include "Class/IoTModule.h"
#include "Class/IoTVariable.h"
extern std::vector<IoTModule*> iotModules; //v3dev: вектор ссылок базового класса IoTModule - интерфейсы для общения со всеми поддерживаемыми системой модулями
//объявляем функцию для добавления модуля в вектор
void* getApiIoTSensorDallasTemp();
void* getApiIoTSensorSHT20();
void* getApiIoTSensorButtonIn();
void* getApiIoTVariableVirtual();
void* getApiIoTVariableButtonOut();
//формируем вектор модулей путем вызова из каждого модуля специальной функции
//в дальнейшем предполагается отключать вызов, если модуль не участвует в сборке
void InitModulesApi() {
iotModules.push_back((IoTModule*) getApiIoTSensorDallasTemp());
iotModules.push_back((IoTModule*) getApiIoTSensorSHT20());
iotModules.push_back((IoTModule*) getApiIoTSensorButtonIn());
iotModules.push_back((IoTModule*) getApiIoTVariableVirtual());
iotModules.push_back((IoTModule*) getApiIoTVariableButtonOut());
}

View File

@@ -154,8 +154,8 @@ boolean mqttConnect() {
if (connected) {
SerialPrint("I", F("MQTT"), F("✔ connected"));
if (currentBroker == 1) jsonWriteStr(configSetupJson, F("warning4"), F("<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #8ef584; padding: 10px;'>Подключено к основному брокеру</p></font></div>"));
if (currentBroker == 2) jsonWriteStr(configSetupJson, F("warning4"), F("<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #8ef584; padding: 10px;'>Подключено к резервному брокеру</p></font></div>"));
if (currentBroker == 1) jsonWriteStr(configSetupJson, F("warning4"), F("Подключено к основному брокеру"));
if (currentBroker == 2) jsonWriteStr(configSetupJson, F("warning4"), F("Подключено к резервному брокеру"));
setLedStatus(LED_OFF);
mqttSubscribe();
res = true;
@@ -163,7 +163,7 @@ boolean mqttConnect() {
mqttConnectAttempts++;
SerialPrint("E", F("MQTT"), "🡆 Attempt No: " + String(mqttConnectAttempts) + " could't connect, retry in " + String(MQTT_RECONNECT_INTERVAL / 1000) + "s");
setLedStatus(LED_FAST);
jsonWriteStr(configSetupJson, F("warning4"), F("<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #fa987a; padding: 10px;'>Не подключено брокеру</p></font></div>"));
jsonWriteStr(configSetupJson, F("warning4"), F("Не подключено брокеру"));
if (mqttConnectAttempts >= CHANGE_BROKER_AFTER) {
mqttConnectAttempts = 0;
if (isSecondBrokerSet()) {
@@ -180,14 +180,14 @@ boolean mqttConnect() {
void mqttCallback(char* topic, uint8_t* payload, size_t length) {
String topicStr = String(topic);
//SerialPrint("I", "=>MQTT", topicStr);
// SerialPrint("I", "=>MQTT", topicStr);
String payloadStr;
payloadStr.reserve(length + 1);
for (size_t i = 0; i < length; i++) {
payloadStr += (char)payload[i];
}
//SerialPrint("I", "=>MQTT", payloadStr);
// SerialPrint("I", "=>MQTT", payloadStr);
if (payloadStr.startsWith("HELLO")) {
SerialPrint("I", F("MQTT"), F("Full update"));
@@ -321,8 +321,8 @@ void publishWidgets() {
line = all_widgets.substring(psn_1, psn_2);
line.replace("\n", "");
line.replace("\r\n", "");
//jsonWriteStr(line, "id", String(counter));
//jsonWriteStr(line, "pageId", String(counter));
// jsonWriteStr(line, "id", String(counter));
// jsonWriteStr(line, "pageId", String(counter));
counter++;
sendMQTT("config", line);
Serial.println("[V] " + line);

View File

@@ -7,7 +7,15 @@
//для того что бы выключить оригинальный лог нужно перейти в файл библиотеки MyGatewayTransportSerial.cpp
//и заккоментировать строку 36 MY_SERIALDEVICE.print(protocolMyMessage2Serial(message));
boolean publishAnyJsonKeyWS(const String& topic, const String& key, const String& data) {
String path = mqttRootDevice + "/" + topic + "/status";
String json = "{}";
jsonWriteStr(json, key, data);
//добавляем топик, выводим в ws
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
}
void loopMySensorsExecute() {
if (mysensorBuf.length()) {
String tmp = selectToMarker(mysensorBuf, ";");
@@ -27,9 +35,15 @@ void loopMySensorsExecute() {
if (command == "3") { //это особое внутреннее сообщение
if (type == "11") { //название ноды
SerialPrint("I", "MySensor", "Node name: " + value);
}
//*
publishAnyJsonKey("MySensors", "Node name:", value);
publishAnyJsonKeyWS("MySensors", "Node name:", value);
}
if (type == "12") { //версия ноды
SerialPrint("I", "MySensor", "Node version: " + value);
//*
publishAnyJsonKey("MySensors", "Node version: ", value);
publishAnyJsonKeyWS("MySensors", "Node version: ", value);
}
}
} else {
@@ -44,13 +58,26 @@ void loopMySensorsExecute() {
addItemAuto(num, key, widget, descr);
descr.replace("#", " ");
SerialPrint("I", "MySensor", "Add new item: " + key + ": " + descr);
//*
publishAnyJsonKey("MySensors", key, descr);
publishAnyJsonKeyWS("MySensors", key, descr);
} else {
descr.replace("#", " ");
SerialPrint("I", "MySensor", "Item already exist: " + key + ": " + descr);
//*
publishAnyJsonKey("MySensors", key, descr);
publishAnyJsonKeyWS("MySensors", key, descr);
}
} else {
descr.replace("#", " ");
SerialPrint("I", "MySensor", "Presentation: " + key + ": " + descr);
//*
publishAnyJsonKey("MySensors", key, descr);
publishAnyJsonKeyWS("MySensors", key, descr);
}
}
if (command == "1") { //это данные
@@ -63,6 +90,9 @@ void loopMySensorsExecute() {
if (mySensorNode != nullptr) {
for (unsigned int i = 0; i < mySensorNode->size(); i++) {
mySensorNode->at(i).onChange(value, key); //вызываем поочередно все экземпляры, там где подойдет там и выполнится
//*
publishAnyJsonKey("MySensors", key, value);
publishAnyJsonKeyWS("MySensors", key, value);
}
}
SerialPrint("I", "MySensor", "node: " + nodeId + ", sensor: " + childSensorId + ", command: " + command + ", type: " + type + ", val: " + value);

View File

@@ -76,6 +76,11 @@ void sendTelegramMsg() {
String msg = sCmd.next();
if (sabject == "often") {
msg.replace("#", " ");
msg.replace("%date%", timeNow->getDateTimeDotFormated());
msg.replace("%weekday%", timeNow->getWeekday());
msg.replace("%IP%", jsonReadStr(configSetupJson, F("ip")));
msg.replace("%name%", jsonReadStr(configSetupJson, F("name")));
myBot->sendMessage(jsonReadInt(configSetupJson, "chatId"), msg);
SerialPrint("<-", F("Telegram"), "chat ID: " + String(jsonReadInt(configSetupJson, "chatId")) + ", msg: " + msg);
} else {
@@ -84,6 +89,11 @@ void sendTelegramMsg() {
jsonWriteStr(telegramMsgJson, sabject, msg);
msg.replace("#", " ");
sabject.replace("#", " ");
msg.replace("%date%", timeNow->getDateTimeDotFormated());
msg.replace("%weekday%", timeNow->getWeekday());
msg.replace("%IP%", jsonReadStr(configSetupJson, F("ip")));
msg.replace("%name%", jsonReadStr(configSetupJson, F("name")));
myBot->sendMessage(jsonReadInt(configSetupJson, "chatId"), msg);
SerialPrint("<-", F("Telegram"), "chat ID: " + String(jsonReadInt(configSetupJson, "chatId")) + ", msg: " + msg);
}

View File

@@ -8,11 +8,14 @@
#endif
#include "Global.h"
String msg = "";
void upgradeInit() {
myNotAsyncActions->add(
do_UPGRADE, [&](void*) {
upgrade_firmware(3);
},
nullptr);
@@ -61,6 +64,8 @@ void getLastVersion() {
}
void upgrade_firmware(int type) {
String scenario_ForUpdate;
String devconfig_ForUpdate;
String configSetup_ForUpdate;
@@ -84,6 +89,8 @@ void upgrade_firmware(int type) {
else if (type == 3) { //spiffs and build
if (upgradeFS()) {
String temp = jsonWriteInt(msg, "upgrade", 3 );
ws.textAll(temp);
writeFile(String(DEVICE_SCENARIO_FILE), scenario_ForUpdate);
writeFile(String(DEVICE_CONFIG_FILE), devconfig_ForUpdate);
writeFile("config.json", configSetup_ForUpdate);
@@ -95,11 +102,18 @@ void upgrade_firmware(int type) {
}
}
bool upgradeFS() {
bool ret = false;
bool upgradeFS() {
bool ret = false;
#ifndef esp8266_1mb
WiFiClient wifiClient;
Serial.printf("Start upgrade %s, please wait...", FS_NAME);
#ifdef esp8266_4mb
ESPhttpUpdate.rebootOnUpdate(false);
t_httpUpdate_return retFS = ESPhttpUpdate.updateFS(wifiClient, serverIP + F("/projects/iotmanager/esp8266/littlefs/littlefs.bin"));
@@ -117,6 +131,8 @@ bool upgradeFS() {
HTTPUpdateResult retFS = httpUpdate.updateSpiffs(wifiClient, serverIP + F("/projects/iotmanager/esp32ms/littlefs/spiffs.bin"));
#endif
if (retFS == HTTP_UPDATE_OK) { //если FS обновилась успешно
String temp = jsonWriteInt(msg, "upgrade", 2);
ws.textAll(temp);
SerialPrint("I", F("Update"), F("FS upgrade done!"));
ret = true;
}
@@ -125,6 +141,8 @@ bool upgradeFS() {
}
bool upgradeBuild() {
String temp = jsonWriteInt(msg, "upgrade", 4 );
ws.textAll(temp);
bool ret = false;
#ifndef esp8266_1mb
WiFiClient wifiClient;
@@ -149,12 +167,16 @@ bool upgradeBuild() {
if (retBuild == HTTP_UPDATE_OK) { //если BUILD обновился успешно
SerialPrint("I", F("Update"), F("BUILD upgrade done!"));
ret = true;
String temp = jsonWriteInt(msg, "upgrade", 5 );
ws.textAll(temp);
}
#endif
return ret;
}
void restartEsp() {
String temp = jsonWriteInt(msg, "upgrade", 6 );
ws.textAll(temp);
Serial.println(F("Restart ESP...."));
delay(1000);
ESP.restart();

View File

@@ -2,7 +2,7 @@
#include "FileSystem.h"
#include "Utils/StringUtils.h"
#include "Utils\SerialPrint.h"
#include "Utils/SerialPrint.h"
const String filepath(const String& filename) {
return filename.startsWith("/") ? filename : "/" + filename;

View File

@@ -1,6 +1,7 @@
#include "Utils/JsonUtils.h"
#include "Utils/FileUtils.h"
#include "Global.h"
#include "Utils/FileUtils.h"
String jsonReadStr(String& json, String name) {
DynamicJsonBuffer jsonBuffer;
@@ -20,6 +21,12 @@ int jsonReadInt(String& json, String name) {
return root[name];
}
float jsonReadFloat(String& json, String name) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
return root[name];
}
String jsonWriteStr(String& json, String name, String value) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);

View File

@@ -1,9 +1,15 @@
#include "Utils\SerialPrint.h"
#include "Utils/SerialPrint.h"
#include "Global.h"
void SerialPrint(String errorLevel, String module, String msg) {
//if (module == "MySensor") {
Serial.println(prettyMillis(millis()) + " [" + errorLevel + "] [" + module + "] " + msg);
String logtoWS = jsonReadStr(configSetupJson, "logtoWS");
if (logtoWS == "true"){
ws.textAll(" [" + errorLevel + "] [" + module + "] " + msg);
}
String logtoMQTT = jsonReadStr(configSetupJson, "logtoMQTT");
if (logtoMQTT == "true"){
publishAnyJsonKey("log", "log", errorLevel + " " + module + " " + msg);
}
//}
}

View File

@@ -62,6 +62,41 @@ String selectFromMarkerToMarker(String str, String tofind, int number) {
return "not found";
}
//преобразовываем байтовый массив в человеческий вид HEX в строке
void hex2string(byte array[], unsigned int len, char buffer[])
{
for (unsigned int i = 0; i < len; i++)
{
byte nib1 = (array[i] >> 4) & 0x0F;
byte nib2 = (array[i] >> 0) & 0x0F;
buffer[i*2+0] = nib1 < 0xA ? '0' + nib1 : 'A' + nib1 - 0xA;
buffer[i*2+1] = nib2 < 0xA ? '0' + nib2 : 'A' + nib2 - 0xA;
}
buffer[len*2] = '\0';
}
inline unsigned char ChartoHex( char ch )
{
return ( ( ch >= 'A' ) ? ( ch - 'A' + 0xA ) : ( ch - '0' ) ) & 0x0F;
}
// str - указатель на массив символов
// bytes - выходной буфер
// функция возвращает колл-во байт
//
int string2hex(const char* str, unsigned char* bytes )
{
unsigned char Hi, Lo;
int i = 0;
while( ( Hi = *str++ ) && ( Lo = *str++ ) )
{
bytes[i++] = ( ChartoHex( Hi ) << 4 ) | ChartoHex( Lo );
}
return i;
}
uint8_t hexStringToUint8(String hex) {
uint8_t tmp = strtol(hex.c_str(), NULL, 0);
if (tmp >= 0x00 && tmp <= 0xFF) {

View File

@@ -1,4 +1,5 @@
#include "Utils/WiFiUtils.h"
#include "FileSystem.h"
void routerConnect() {
@@ -63,7 +64,7 @@ bool startAPMode() {
SerialPrint("I", "WIFI", "AP IP: " + myIP.toString());
jsonWriteStr(configSetupJson, "ip", myIP.toString());
//if (jsonReadInt(configOptionJson, "pass_status") != 1) {
// if (jsonReadInt(configOptionJson, "pass_status") != 1) {
ts.add(
WIFI_SCAN, 10 * 1000, [&](void*) {
String sta_ssid = jsonReadStr(configSetupJson, "routerssid");
@@ -88,7 +89,7 @@ boolean RouterFind(String ssid) {
if (n == -2) { //Сканирование не было запущено, запускаем
SerialPrint("I", "WIFI", "start scanning");
WiFi.scanNetworks(true, false); //async, show_hidden
WiFi.scanNetworks(true, false); // async, show_hidden
}
else if (n == -1) { //Сканирование все еще выполняется
@@ -146,25 +147,25 @@ void wifiSignalInit() {
switch (RSSIquality()) {
case 0:
jsonWriteStr(configSetupJson, F("signal"), F("Уровень WiFi сигнала: <font color='red'>не подключено к роутеру</font>"));
jsonWriteStr(configSetupJson, F("signal"), F("не подключено к роутеру"));
break;
case 1:
jsonWriteStr(configSetupJson, F("signal"), F("Уровень WiFi сигнала: <font color='red'>нет сигнала</font>"));
jsonWriteStr(configSetupJson, F("signal"), F("нет сигнала"));
break;
case 2:
jsonWriteStr(configSetupJson, F("signal"), F("Уровень WiFi сигнала: <font color='red'>очень низкий</font>"));
jsonWriteStr(configSetupJson, F("signal"), F("очень низкий"));
break;
case 3:
jsonWriteStr(configSetupJson, F("signal"), F("Уровень WiFi сигнала: <font color='orange'>низкий</font>"));
jsonWriteStr(configSetupJson, F("signal"), F("низкий"));
break;
case 4:
jsonWriteStr(configSetupJson, F("signal"), F("Уровень WiFi сигнала: <font color='green'>хороший</font>"));
jsonWriteStr(configSetupJson, F("signal"), F("хороший"));
break;
case 5:
jsonWriteStr(configSetupJson, F("signal"), F("Уровень WiFi сигнала: <font color='green'>очень хороший</font>"));
jsonWriteStr(configSetupJson, F("signal"), F("очень хороший"));
break;
case 6:
jsonWriteStr(configSetupJson, F("signal"), F("Уровень WiFi сигнала: <font color='green'>отличный</font>"));
jsonWriteStr(configSetupJson, F("signal"), F("отличный"));
break;
}
},

View File

@@ -1,4 +1,4 @@
#include "Utils/StatUtils.h"
#include "Utils/statUtils.h"
#include <Arduino.h>
#include <EEPROM.h>

View File

@@ -1,4 +1,5 @@
#include "Web.h"
#include "BufferExecute.h"
#include "Class/NotAsync.h"
#include "Global.h"
@@ -28,13 +29,13 @@ void web_init() {
if (request->hasArg(F("addPreset"))) {
addPreset2(request->getParam(F("addPreset"))->value().toInt());
jsonWriteStr(configSetupJson, F("warning1"), F("<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #ffc7c7; padding: 10px;'>Требуется перезагрузка</p></font></div>"));
jsonWriteStr(configSetupJson, F("warning1"), F("Требуется перезагрузка"));
request->redirect(F("/?set.device"));
}
if (request->hasArg(F("delChoosingItems"))) {
jsonWriteStr(configSetupJson, F("warning1"), F("<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #ffc7c7; padding: 10px;'>Требуется перезагрузка</p></font></div>"));
jsonWriteStr(configSetupJson, F("warning1"), F("Требуется перезагрузка"));
myNotAsyncActions->make(do_delChoosingItems);
request->send(200);
}
@@ -44,7 +45,7 @@ void web_init() {
#ifdef EnableLogging
cleanLogAndData();
#endif
jsonWriteStr(configSetupJson, F("warning1"), F("<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #ffc7c7; padding: 10px;'>Требуется перезагрузка</p></font></div>"));
jsonWriteStr(configSetupJson, F("warning1"), F("Требуется перезагрузка"));
request->redirect(F("/?set.device"));
}
@@ -174,7 +175,7 @@ void web_init() {
}
//==============================mqtt settings=============================================
//primary
// primary
if (request->hasArg(F("mqttServer"))) {
jsonWriteStr(configSetupJson, F("mqttServer"), request->getParam(F("mqttServer"))->value());
saveConfig();
@@ -206,7 +207,7 @@ void web_init() {
myNotAsyncActions->make(do_MQTTPARAMSCHANGED);
request->send(200);
}
//secondary
// secondary
if (request->hasArg(F("mqttServer2"))) {
jsonWriteStr(configSetupJson, F("mqttServer2"), request->getParam(F("mqttServer2"))->value());
saveConfig();
@@ -240,7 +241,7 @@ void web_init() {
}
if (request->hasArg("mqttsend")) {
//myNotAsyncActions->make(do_MQTTUDP);
// myNotAsyncActions->make(do_MQTTUDP);
request->send(200);
}
@@ -336,7 +337,7 @@ void web_init() {
serverIP = jsonReadStr(configSetupJson, "serverip");
request->send(200);
}
//set?order=button_1
// set?order=button_1
if (request->hasArg("order")) {
String order = request->getParam("order")->value();
order.replace("_", " ");
@@ -351,7 +352,7 @@ void web_init() {
request->send(200);
}
//gate mode
// gate mode
if (request->hasArg("gateAuto")) {
bool value = request->getParam("gateAuto")->value().toInt();
@@ -359,19 +360,18 @@ void web_init() {
saveConfig();
request->send(200);
}
});
//server.on("/del", HTTP_GET, [](AsyncWebServerRequest* request) {
// if (request->hasArg("file") && request->hasArg("line")) {
// String fileName = request->getParam("file")->value();
// Serial.println(fileName);
// int line = request->getParam("line")->value().toInt();
// Serial.println(line);
// myNotAsyncActions->make(do_delChoosingItems);
// request->redirect(F("/?set.device"));
// }
//});
// server.on("/del", HTTP_GET, [](AsyncWebServerRequest* request) {
// if (request->hasArg("file") && request->hasArg("line")) {
// String fileName = request->getParam("file")->value();
// Serial.println(fileName);
// int line = request->getParam("line")->value().toInt();
// Serial.println(line);
// myNotAsyncActions->make(do_delChoosingItems);
// request->redirect(F("/?set.device"));
// }
// });
server.on("/check", HTTP_GET, [](AsyncWebServerRequest* request) {
myNotAsyncActions->make(do_GETLASTVERSION);
@@ -402,8 +402,8 @@ void web_init() {
});
/*
* Upgrade
*/
* Upgrade
*/
server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest* request) {
myNotAsyncActions->make(do_UPGRADE);
request->send(200, "text/html");

View File

@@ -3,7 +3,13 @@
#include "Utils/FileUtils.h"
#include "Utils/WebUtils.h"
#include "FSEditor.h"
#include "Upgrade.h"
#include "Class/NotAsync.h"
#include "items/vLogging.h"
int flagq ;
AsyncWebSocket ws ("/ws");
AsyncEventSource events("/events");
namespace HttpServer {
@@ -84,12 +90,100 @@ void init() {
SerialPrint("I", F("HTTP"), F("HttpServer Init"));
}
///////////
#ifndef LAYOUT_IN_RAM
void publishWidgetsWS() {
String str="";
auto file = seekFile("layout.txt");
if (!file) {
SerialPrint("E", F("WS"), F("no file layout.txt"));
return;
}
while (file.available()) {
String payload = file.readStringUntil('\n');
if (str==""){
str += payload;
}else {str += "," + payload;}
}
file.close();
SerialPrint("I", "WS", "widgets: " + str);
ws.textAll(str);
}
void publishStateWS() {
String mystr="";
String str;
if (configLiveJson != "{}") {
str += configLiveJson;
}
if (configStoreJson != "{}") {
str += "," + configStoreJson;
}
str.replace("{", "");
str.replace("}", "");
str.replace("\"", "");
str += ",";
while (str.length() != 0) {
String tmp = selectToMarker(str, ",");
String topic = selectToMarker(tmp, ":");
String state = deleteBeforeDelimiter(tmp, ":");
if (topic != "" && state != "") {
String json = "{}";
jsonWriteStr(json, "status", state);
jsonWriteStr(json, "topic", mqttRootDevice + "/" + topic + "/status");
SerialPrint("I", "ws", json.c_str());
if (mystr==""){
mystr += json;
}else {mystr += "," + json;}
}
str = deleteBeforeDelimiter(str, ",");
}
ws.textAll(mystr);
}
/*
boolean publishStatusWS(const String& topic, const String& data) {
String path = mqttRootDevice + "/" + topic + "/status";
String json = "{}";
jsonWriteStr(json, "status", data);
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
}
*/
boolean publishAnyJsonKeyWS(const String& topic, const String& key, const String& data) {
String path = mqttRootDevice + "/" + topic + "/status";
String json = "{}";
jsonWriteStr(json, key, data);
//добавляем топик, выводим в ws
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
}
#endif
/////////
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
#ifdef WS_enable
#ifdef WEBSOCKET_ENABLED
if (type == WS_EVT_CONNECT) {
Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
client->printf(json.c_str(), client->id());
// client->printf(json.c_str(), client->id());
//client->ping();
} else if (type == WS_EVT_DISCONNECT) {
Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id());
@@ -116,6 +210,121 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
}
}
Serial.printf("%s\n", msg.c_str());
//->
//если пришло HELLO публикуем виджеты и статусы
if (msg.startsWith("HELLO")) {
SerialPrint("I", F("WS"), F("Full update"));
publishWidgetsWS();
publishStateWS();
flagq = 1;
}
//если пришло UPGRADE
if (msg.startsWith("upgrade")) {
// SerialPrint("I", F("WS"), F("do_UPGRADEstart"));
myNotAsyncActions->make(do_UPGRADE);
String temp = jsonWriteInt(msg, "upgrade", 1 );
ws.textAll(temp);
}
String upgrade = jsonReadStr(msg, "upgrade");
if (upgrade != ""){
// SerialPrint("I", F("WS"), F("do_UPGRADE"));
myNotAsyncActions->make(do_UPGRADE);
String temp = jsonWriteInt(msg, "upgrade", 1 );
ws.textAll(temp);
}
//отправляем конфигурацию на ESP
if (msg.startsWith("getconfigsetupjson")) {
ws.textAll(configSetupJson);
// Serial.printf("%s\n", configSetupJson.c_str());
}
//отправляем NetworkMap в ESP
if (msg.startsWith("getNetworkMap")) {
String NetworkMap= readFile("NetworkMap.json", 409600);
// NetworkMap = NetworkMap.replace("\r\n", "");
ws.textAll(NetworkMap);
}
//отправляем файл в ESP
String getFileName = jsonReadStr(msg, "getFileName");
if (getFileName !=""){
String getFile= readFile(getFileName, 409600);
// getFile.replace("\n", " ");
getFile="{getFileText:'"+getFile+"', getFileName: '"+getFileName+"'}";
jsonWriteStr(getFile, "getFileName", getFileName);
ws.textAll(getFile);
Serial.printf("%s\n getFileName: ", getFileName.c_str());
Serial.printf("%s\n getFile: ", getFile.c_str());
}
//получаем файл от ESP
String setFileName = jsonReadStr(msg, "setFileName");
if (setFileName !=""){
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(msg);
root.remove("setFileName");
String newmsg;
root.printTo(newmsg);
writeFile(setFileName,newmsg);
//Serial.printf("%s\n setFileName: ", setFileName.c_str());
Serial.printf("%s\n text: ", newmsg.c_str());
}
//получаем NetworkMap от ESP
String NetworkMap = jsonReadStr(msg, "NetworkMap");
if (NetworkMap !=""){
writeFile("NetworkMap.json", NetworkMap.c_str());
// ws.textAll(NetworkMap);
}
//перезагрузка
String command = jsonReadStr(msg, "command");
if (command !="" && jsonReadStr(msg, "command")=="reboot"){
ESP.restart();
}
//получаем конфигурацию от ESP
String changeConf = jsonReadStr(msg, "setconfigsetupjson");
if (changeConf = "1"){
jsonWriteStr(configSetupJson, jsonReadStr(msg, "name"), jsonReadStr(msg, "val"));
saveConfig();
Serial.printf("%s\n", jsonReadStr(msg, "name").c_str(), jsonReadStr(msg, "val").c_str());
}
// если пришло в control управляем
String path = jsonReadStr(msg, "path");
String status = jsonReadStr(msg, "status");
if (path.indexOf("control") != -1) {
String key = selectFromMarkerToMarker(path, "/", 3);
String order;
order += key;
order += " ";
order += status;
order += ",";
loopCmdAdd(order);
}
if (info->opcode == WS_TEXT)
client->text("{}");
@@ -200,7 +409,7 @@ void initOta() {
}
void initWS() {
#ifdef WS_enable
#ifdef WEBSOCKET_ENABLED
ws.onEvent(onWsEvent);
server.addHandler(&ws);
events.onConnect([](AsyncEventSourceClient *client) {

108
src/YourSensor.cpp Normal file
View File

@@ -0,0 +1,108 @@
#include "YourSensor.h"
#include "Global.h"
#include "Utils/JsonUtils.h"
#include "Utils/StringUtils.h"
//подключаем необходимые файлы библиотеки
//#include "Adafruit_ADS1X15.h"
#include "Adafruit_AHTX0.h"
#include "BH1750.h"
#include "ClosedCube_HDC1080.h"
#include "LiquidCrystal_I2C.h"
//создаем объект HDC1080
ClosedCube_HDC1080 hdc1080;
//создаем объект AHTX0
Adafruit_AHTX0 aht;
Adafruit_Sensor *aht_humidity, *aht_temp;
sensors_event_t tmpEvent_t;
//создаем объект LCD
LiquidCrystal_I2C LCD(0x27, 16, 2);
//создаем объект BH1750
BH1750 lightMeter;
//создаем объект ADS1015
//Adafruit_ADS1015 ads;
float yourSensorReading(String type, String paramsAny) {
float value;
//========================================================HDC1080================================================================
if (type == "HDC1080_temp") {
HDC1080_init(jsonReadStr(paramsAny, "addr"));
value = hdc1080.readTemperature();
}
if (type == "HDC1080_hum") {
HDC1080_init(jsonReadStr(paramsAny, "addr"));
value = hdc1080.readHumidity();
}
//==========================================================AHTX0=================================================================
if (type == "AHTX0_temp") {
AHTX0_init();
aht_temp->getEvent(&tmpEvent_t);
value = tmpEvent_t.temperature;
}
if (type == "AHTX0_hum") {
AHTX0_init();
aht_humidity->getEvent(&tmpEvent_t);
value = tmpEvent_t.relative_humidity;
}
//==========================================================LCD=================================================================
if (type == "LCD") {
LCD_init();
LCD.setCursor(jsonReadInt(paramsAny, "с"), jsonReadInt(paramsAny, "k"));
String toPrint = jsonReadStr(paramsAny, "descr") + " " + jsonReadStr(configLiveJson, jsonReadStr(paramsAny, "val"));
LCD.print(toPrint);
}
//==========================================================BH1750=================================================================
if (type == "BH1750_lux") {
BH1750_init();
value = lightMeter.readLightLevel();
}
return value;
}
void HDC1080_init(String addr) {
static bool HDC1080_flag = true;
if (HDC1080_flag) {
hdc1080.begin(hexStringToUint8(addr));
HDC1080_flag = false;
}
}
void AHTX0_init() {
static bool AHTX0_flag = true;
if (AHTX0_flag) {
if (!aht.begin()) {
Serial.println("Failed to find AHT10/AHT20 chip");
// return -127;
}
aht_temp = aht.getTemperatureSensor();
aht_temp->printSensorDetails();
aht_humidity = aht.getHumiditySensor();
aht_humidity->printSensorDetails();
AHTX0_flag = false;
}
}
void LCD_init() {
static bool LCD_flag = true;
if (LCD_flag) {
LCD.init(); //инициализация дисплея
LCD.backlight(); //включаем подсветку
}
}
void BH1750_init() {
static bool BH1750_flag = true;
if (BH1750_flag) {
lightMeter.begin();
BH1750_flag = false;
}
}

View File

@@ -1,28 +0,0 @@
#include "Consts.h"
#ifdef EnableButtonIn
#include "BufferExecute.h"
#include "items/ButtonInClass.h"
//==========================================Модуль физических кнопок========================================
//button-in switch1 toggle Кнопки Свет 1 pin[2] db[20]
//==========================================================================================================
boolean but[NUM_BUTTONS];
Bounce *buttons = new Bounce[NUM_BUTTONS];
ButtonInClass myButtonIn;
void buttonIn() {
myButtonIn.update();
String key = myButtonIn.gkey();
String pin = myButtonIn.gpin();
sCmd.addCommand(key.c_str(), buttonInSet);
myButtonIn.init();
myButtonIn.switchStateSetDefault();
myButtonIn.clear();
}
void buttonInSet() {
String key = sCmd.order();
String state = sCmd.next();
myButtonIn.switchChangeVirtual(key, state);
}
#endif

View File

@@ -1,94 +0,0 @@
#include "Consts.h"
#ifdef EnableButtonOut
#include <Arduino.h>
#include "BufferExecute.h"
#include "Class/LineParsing.h"
#include "Global.h"
#include "SoftUART.h"
#include "items/vButtonOut.h"
//this class save data to flash
ButtonOut::ButtonOut(String pin, boolean inv, String key, String type) {
_pin = pin;
_inv = inv;
_key = key;
_type = type;
#ifdef ESP_MODE
if (_pin != "") {
pinMode(_pin.toInt(), OUTPUT);
}
int state = jsonReadInt(configStoreJson, key); //прочитали из памяти
this->execute(String(state)); //установили это состояние
#endif
#ifdef GATE_MODE
//TO DO запросили ноду о состоянии реле
//установили в это состояние кнопку в приложении
//если нода не ответила - кнопку сделать красным цветом
#endif
}
ButtonOut::~ButtonOut() {}
void ButtonOut::execute(String state) {
#ifdef ESP_MODE
if (state != "" && _pin != "") {
if (state == "change") {
state = String(!digitalRead(_pin.toInt()));
digitalWrite(_pin.toInt(), state.toInt());
} else {
if (_inv) {
digitalWrite(_pin.toInt(), !state.toInt());
} else {
digitalWrite(_pin.toInt(), state.toInt());
}
}
}
#endif
#ifdef GATE_MODE
//отправили ноде команду на вкл выкл
//получили обратную связь - переставили кнопку в приложении
//не получили обратную связь - сделали кнопку красной
#endif
eventGen2(_key, state);
jsonWriteInt(configStoreJson, _key, state.toInt());
saveStore();
publishStatus(_key, state);
}
MyButtonOutVector* myButtonOut = nullptr;
void buttonOut() {
myLineParsing.update();
String key = myLineParsing.gkey();
String pin = myLineParsing.gpin();
String inv = myLineParsing.ginv();
String type = myLineParsing.gtype();
bool invb = false;
if (inv.toInt() == 1) invb = true;
myLineParsing.clear();
buttonOut_EnterCounter++;
addKey(key, buttonOut_KeyList, buttonOut_EnterCounter);
static bool firstTime = true;
if (firstTime) myButtonOut = new MyButtonOutVector();
firstTime = false;
myButtonOut->push_back(ButtonOut(pin, invb, key, type));
sCmd.addCommand(key.c_str(), buttonOutExecute);
}
void buttonOutExecute() {
String key = sCmd.order();
String state = sCmd.next();
int number = getKeyNum(key, buttonOut_KeyList);
if (myButtonOut != nullptr) {
if (number != -1) {
myButtonOut->at(number).execute(state);
}
}
}
#endif

View File

@@ -32,6 +32,12 @@ void CountDownClass::loop() {
String time = String(prettyMillis(sec * 1000));
jsonWriteStr(configLiveJson, _key, time);
publishStatus(_key, time);
String path = mqttRootDevice + "/" + _key + "/status";
String json = "{}";
jsonWriteStr(json, "status", time);
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
sec--;
if (sec < 0) {
_countDownPeriod = 0;
@@ -48,10 +54,8 @@ void countDown() {
countDown_EnterCounter++;
addKey(key, countDown_KeyList, countDown_EnterCounter);
//Serial.println(countDown_EnterCounter);
//Serial.println(countDown_KeyList);
static bool firstTime = true;
if (firstTime) myCountDown = new MyCountDownVector();
firstTime = false;

View File

@@ -31,6 +31,12 @@ void Input::execute(String value) {
jsonWriteStr(configStoreJson, _key, value);
saveStore();
publishStatus(_key, value);
String path = mqttRootDevice + "/" + _key + "/status";
String json = "{}";
jsonWriteStr(json, "status", value);
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
}
MyInputVector* myInput = nullptr;

View File

@@ -166,7 +166,78 @@ void loggingExecute() {
}
}
void choose_log_date_and_sendWS() {
String all_line = logging_KeyList;
while (all_line.length() != 0) {
String tmp = selectToMarker(all_line, ",");
sendLogDataWS("/logs/" + tmp + ".txt", tmp);
all_line = deleteBeforeDelimiter(all_line, ",");
}
}
void sendLogDataWS(String file, String topic) {
File configFile = FileFS.open(file, "r");
if (!configFile) {
return;
}
configFile.seek(0, SeekSet);
int i = 0;
String buf = "{}";
String json_array;
String unix_time;
String value;
unsigned int psn;
unsigned int sz = configFile.size();
do {
i++;
psn = configFile.position();
String line = configFile.readStringUntil('\n');
unix_time = selectToMarker(line, " ");
jsonWriteInt(buf, "x", unix_time.toInt());
value = deleteBeforeDelimiter(line, " ");
jsonWriteFloat(buf, "y1", value.toFloat());
if (unix_time != "" || value != "") {
json_array += buf + ",";
}
int grafmax = jsonReadInt(configSetupJson, "grafmax");
if (grafmax != 0) {
if (i >= grafmax) {
json_array = "{\"status\":[" + json_array + "]}";
json_array.replace("},]}", "}]}");
// publishChart(topic, json_array);
// добавляем топик, выводим в ws
String path = mqttRootDevice + "/" + topic;
String json = "{}";
json=json_array;
jsonWriteStr(json, "topic", path);
ws.textAll(json);
json_array = "";
i = 0;
}
}
} while (psn < sz);
configFile.close();
json_array = "{\"status\":[" + json_array + "]}";
json_array.replace("},]}", "}]}");
//publishChart(topic, json_array);
// добавляем топик, выводим в ws
String path = mqttRootDevice + "/" + topic;
String json = "{}";
json=json_array;
jsonWriteStr(json, "topic", path);
ws.textAll(json);
}
void choose_log_date_and_send() {
String all_line = logging_KeyList;
while (all_line.length() != 0) {
String tmp = selectToMarker(all_line, ",");
@@ -205,7 +276,8 @@ void sendLogData(String file, String topic) {
json_array = "{\"status\":[" + json_array + "]}";
json_array.replace("},]}", "}]}");
publishChart(topic, json_array);
json_array = "";
json_array = "";
i = 0;
}
}
@@ -216,6 +288,7 @@ void sendLogData(String file, String topic) {
json_array = "{\"status\":[" + json_array + "]}";
json_array.replace("},]}", "}]}");
publishChart(topic, json_array);
}
void cleanLogAndData() {

View File

@@ -19,6 +19,12 @@ void Output::execute(String value) {
eventGen2(_key, value);
jsonWriteStr(configLiveJson, _key, value);
publishStatus(_key, value);
String path = mqttRootDevice + "/" + _key + "/status";
String json = "{}";
jsonWriteStr(json, "status", value);
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
//publishLastUpdateTime(_key, timeNow->getTime());
}
@@ -46,6 +52,9 @@ void outputExecute() {
value.replace("#", " ");
value.replace("%date%", timeNow->getDateTimeDotFormated());
value.replace("%weekday%", timeNow->getWeekday());
value.replace("%IP%", jsonReadStr(configSetupJson, F("ip")));
value.replace("%name%", jsonReadStr(configSetupJson, F("name")));
int number = getKeyNum(key, output_KeyList);

View File

@@ -25,6 +25,12 @@ void PwmOut::execute(String state) {
jsonWriteInt(configStoreJson, _key, state.toInt());
saveStore();
publishStatus(_key, state);
String path = mqttRootDevice + "/" + _key + "/status";
String json = "{}";
jsonWriteStr(json, "status", state);
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
}
MyPwmOutVector* myPwmOut = nullptr;

View File

@@ -45,6 +45,12 @@ void SensorAnalog::readAnalog() {
eventGen2(_key, String(valueFloat));
jsonWriteStr(configLiveJson, _key, String(valueFloat));
publishStatus(_key, String(valueFloat));
String path = mqttRootDevice + "/" + _key + "/status";
String json = "{}";
jsonWriteStr(json, "status", String(valueFloat));
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _key + "' data: " + String(valueFloat));
}

71
src/items/vSensorAny.cpp Normal file
View File

@@ -0,0 +1,71 @@
#include "Consts.h"
#ifdef EnableSensorAny
#include <Arduino.h>
#include "BufferExecute.h"
#include "Class/LineParsing.h"
#include "Global.h"
#include "YourSensor.h"
#include "items/vSensorAny.h"
SensorAny::SensorAny(const String& paramsAny) {
_paramsAny = paramsAny;
_interval = jsonReadInt(_paramsAny, "int");
_c = jsonReadFloat(_paramsAny, "c");
_k = jsonReadFloat(_paramsAny, "k");
_key = jsonReadStr(_paramsAny, "key");
_addr = jsonReadStr(_paramsAny, "addr");
_type = jsonReadStr(_paramsAny, "type");
_val = jsonReadStr(_paramsAny, "val");
_descr = jsonReadStr(_paramsAny, "descr");
}
SensorAny::~SensorAny() {}
void SensorAny::loop() {
difference = millis() - prevMillis;
if (difference >= _interval * 1000) {
prevMillis = millis();
read();
}
}
void SensorAny::read() {
float value = yourSensorReading(_type, _paramsAny);
value = value * _c;
eventGen2(_key, String(value));
jsonWriteStr(configLiveJson, _key, String(value));
publishStatus(_key, String(value));
String path = mqttRootDevice + "/" + _key + "/status";
String json = "{}";
jsonWriteStr(json, "status", String(value));
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _key + "' data: " + String(value));
}
MySensorAnyVector* mySensorAny = nullptr;
void AnySensor() {
String params = "{}";
myLineParsing.update();
jsonWriteStr(params, "key", myLineParsing.gkey());
jsonWriteStr(params, "addr", myLineParsing.gaddr());
jsonWriteStr(params, "int", myLineParsing.gint());
jsonWriteStr(params, "c", myLineParsing.gc());
jsonWriteStr(params, "k", myLineParsing.gk());
jsonWriteStr(params, "val", myLineParsing.gval());
jsonWriteStr(params, "type", myLineParsing.gtype());
jsonWriteStr(params, "descr", myLineParsing.gdescr());
myLineParsing.clear();
static bool firstTime = true;
if (firstTime) mySensorAny = new MySensorAnyVector();
firstTime = false;
mySensorAny->push_back(SensorAny(params));
}
#endif

View File

@@ -48,16 +48,34 @@ void SensorBme280::read() {
eventGen2(_paramsTmp.key, String(tmp));
jsonWriteStr(configLiveJson, _paramsTmp.key, String(tmp));
publishStatus(_paramsTmp.key, String(tmp));
String path = mqttRootDevice + "/" +_paramsTmp.key + "/status";
String json = "{}";
jsonWriteStr(json, "status", String(tmp));
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsTmp.key + "' data: " + String(tmp));
eventGen2(_paramsHum.key, String(hum));
jsonWriteStr(configLiveJson, _paramsHum.key, String(hum));
publishStatus(_paramsHum.key, String(hum));
path = mqttRootDevice + "/" +_paramsHum.key + "/status";
json = "{}";
jsonWriteStr(json, "status", String(hum));
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsHum.key + "' data: " + String(hum));
eventGen2(_paramsPrs.key, String(prs));
jsonWriteStr(configLiveJson, _paramsPrs.key, String(prs));
publishStatus(_paramsPrs.key, String(prs));
path = mqttRootDevice + "/" +_paramsPrs.key + "/status";
json = "{}";
jsonWriteStr(json, "status", String(prs));
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsPrs.key + "' data: " + String(prs));
}

View File

@@ -44,11 +44,23 @@ void SensorBmp280::read() {
eventGen2(_paramsTmp.key, String(tmp));
jsonWriteStr(configLiveJson, _paramsTmp.key, String(tmp));
publishStatus(_paramsTmp.key, String(tmp));
String path = mqttRootDevice + "/" +_paramsTmp.key + "/status";
String json = "{}";
jsonWriteStr(json, "status", String(tmp));
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsTmp.key + "' data: " + String(tmp));
eventGen2(_paramsPrs.key, String(prs));
jsonWriteStr(configLiveJson, _paramsPrs.key, String(prs));
publishStatus(_paramsPrs.key, String(prs));
path = mqttRootDevice + "/" +_paramsPrs.key + "/status";
json = "{}";
jsonWriteStr(json, "status", String(prs));
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsPrs.key + "' data: " + String(prs));
}

View File

@@ -41,11 +41,23 @@ void SensorCcs811::read() {
eventGen2(_paramsPpm.key, String(co2));
jsonWriteStr(configLiveJson, _paramsPpm.key, String(co2));
publishStatus(_paramsPpm.key, String(co2));
String path = mqttRootDevice + "/" +_paramsPpm.key + "/status";
String json = "{}";
jsonWriteStr(json, "status", String(co2));
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsPpm.key + "' data: " + String(co2));
eventGen2(_paramsPpb.key, String(ppm));
jsonWriteStr(configLiveJson, _paramsPpb.key, String(ppm));
publishStatus(_paramsPpb.key, String(ppm));
path = mqttRootDevice + "/" +_paramsPpb.key + "/status";
json = "{}";
jsonWriteStr(json, "status", String(ppm));
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsPpb.key + "' data: " + String(ppm));
} else {
SerialPrint("E", "Sensor CCS", "Error");

View File

@@ -1,60 +0,0 @@
#include "Consts.h"
#ifdef EnableSensorDallas
#include "items/vSensorDallas.h"
#include "BufferExecute.h"
#include "Class/LineParsing.h"
#include "Global.h"
#include <Arduino.h>
OneWire* oneWire;
DallasTemperature sensors;
SensorDallas::SensorDallas(unsigned long interval, unsigned int pin, unsigned int index, String key) {
_interval = interval * 1000;
_key = key;
_pin = pin;
_index = index;
oneWire = new OneWire((uint8_t)_pin);
sensors.setOneWire(oneWire);
sensors.begin();
sensors.setResolution(12);
}
SensorDallas::~SensorDallas() {}
void SensorDallas::loop() {
currentMillis = millis();
difference = currentMillis - prevMillis;
if (difference >= _interval) {
prevMillis = millis();
readDallas();
}
}
void SensorDallas::readDallas() {
sensors.requestTemperaturesByIndex(_index);
float value = sensors.getTempCByIndex(_index);
eventGen2(_key, String(value));
jsonWriteStr(configLiveJson, _key, String(value));
publishStatus(_key, String(value));
SerialPrint("I", "Sensor", "'" + _key + "' data: " + String(value));
}
MySensorDallasVector* mySensorDallas2 = nullptr;
void dallas() {
myLineParsing.update();
String interval = myLineParsing.gint();
String pin = myLineParsing.gpin();
String index = myLineParsing.gindex();
String key = myLineParsing.gkey();
myLineParsing.clear();
static bool firstTime = true;
if (firstTime) mySensorDallas2 = new MySensorDallasVector();
firstTime = false;
mySensorDallas2->push_back(SensorDallas(interval.toInt(), pin.toInt(), index.toInt(), key));
}
#endif

View File

@@ -44,11 +44,23 @@ void SensorDht::readTmpHum() {
eventGen2(_paramsTmp.key, String(tmp));
jsonWriteStr(configLiveJson, _paramsTmp.key, String(tmp));
publishStatus(_paramsTmp.key, String(tmp));
String path = mqttRootDevice + "/" +_paramsTmp.key + "/status";
String json = "{}";
jsonWriteStr(json, "status", String(tmp));
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsTmp.key + "' data: " + String(tmp));
eventGen2(_paramsHum.key, String(hum));
jsonWriteStr(configLiveJson, _paramsHum.key, String(hum));
publishStatus(_paramsHum.key, String(hum));
path = mqttRootDevice + "/" +_paramsHum.key + "/status";
json = "{}";
jsonWriteStr(json, "status", String(hum));
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsHum.key + "' data: " + String(hum));
} else {

View File

@@ -1,51 +0,0 @@
//#include "items/vSensorImpulsIn.h"
//
//#include "BufferExecute.h"
//#include "Class/LineParsing.h"
//#include "Global.h"
//#include "SoftUART.h"
//
//SensorImpulsIn::SensorImpulsIn(const paramsImpulsIn& paramsImpuls) {
// _paramsImpuls = paramsImpulsIn(paramsImpuls);
// pinMode(14, INPUT);
// //pinMode(_paramsImpuls.pin, INPUT_PULLUP);
// //attachInterrupt(digitalPinToInterrupt(14), MYinterrupt, CHANGE);
//}
//
//SensorImpulsIn::~SensorImpulsIn() {}
//
////void SensorImpulsIn::read() {
// float voltage; //= (impulsIn->values()->voltage * _paramsV.c) + _paramsV.k;
//
// eventGen2(_paramsImpuls.key, String(voltage));
// jsonWriteStr(configLiveJson, _paramsImpuls.key, String(voltage));
// publishStatus(_paramsImpuls.key, String(voltage));
// SerialPrint("I", "Sensor", "'" + _paramsImpuls.key + "' data: " + String(voltage));
//}
//
//MySensorImpulsInVector* mySensorImpulsIn = nullptr;
//
//void impulsInSensor() {
// myLineParsing.update();
// String key = myLineParsing.gkey();
// String pin = myLineParsing.gpin();
// String c = myLineParsing.gc();
// String k = myLineParsing.gk();
// myLineParsing.clear();
//
// static paramsImpulsIn paramsImpuls;
//
// paramsImpuls.key = key;
// paramsImpuls.pin = pin.toInt();
// paramsImpuls.c = c.toFloat();
// paramsImpuls.k = k.toFloat();
//
// static bool firstTime = true;
// if (firstTime) mySensorImpulsIn = new MySensorImpulsInVector();
// firstTime = false;
// mySensorImpulsIn->push_back(SensorImpulsIn(paramsImpuls));
//}
//
//void MYinterrupt() {
// Serial.println("interrupt!");
//}

View File

@@ -37,6 +37,12 @@ void SensorNode::onChange(String newValue, String incommingKey) {
eventGen2(_params.key, newValue);
jsonWriteStr(configLiveJson, _params.key, newValue);
publishStatus(_params.key, newValue);
String path = mqttRootDevice + "/" +_params.key + "/status";
String json = "{}";
jsonWriteStr(json, "status", newValue);
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
_updateTime = timeNow->getDateTimeDotFormated();
@@ -48,17 +54,72 @@ void SensorNode::onChange(String newValue, String incommingKey) {
void SensorNode::publish() {
if (_minutesPassed < _params.tm1.toInt()) {
publishAnyJsonKey(_params.key, "info", String(_minutesPassed) + " min");
String path = mqttRootDevice + "/" + _params.key + "/status";
String json = "{}";
jsonWriteStr(json, "info", String(_minutesPassed) + " min");
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
publishAnyJsonKey(_params.key, "color", "");
path = mqttRootDevice + "/" + _params.key + "/status";
json = "{}";
jsonWriteStr(json, "color", "");
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
} else if (_minutesPassed >= _params.tm1.toInt() && _minutesPassed < _params.tm2.toInt()) {
publishAnyJsonKey(_params.key, "info", String(_minutesPassed) + " min");
String path = mqttRootDevice + "/" + _params.key + "/status";
String json = "{}";
jsonWriteStr(json, "info", String(_minutesPassed) + " min");
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
publishAnyJsonKey(_params.key, "color", "orange");
path = mqttRootDevice + "/" + _params.key + "/status";
json = "{}";
jsonWriteStr(json, "color", "orange");
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
} else if (_minutesPassed >= _params.tm2.toInt()) {
if (_updateTime == "") {
publishAnyJsonKey(_params.key, "info", "offline");
String path = mqttRootDevice + "/" + _params.key + "/status";
String json = "{}";
jsonWriteStr(json, "info", "offline");
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
} else {
publishAnyJsonKey(_params.key, "info", _updateTime);
String path = mqttRootDevice + "/" + _params.key + "/status";
String json = "{}";
jsonWriteStr(json, "info", _updateTime);
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
}
publishAnyJsonKey(_params.key, "color", "red");
String path = mqttRootDevice + "/" + _params.key + "/status";
String json = "{}";
jsonWriteStr(json, "color", "red");
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
}
}

View File

@@ -38,26 +38,56 @@ void SensorPzem::read() {
eventGen2(_paramsV.key, String(voltage));
jsonWriteStr(configLiveJson, _paramsV.key, String(voltage));
publishStatus(_paramsV.key, String(voltage));
String path = mqttRootDevice + "/" +_paramsV.key + "/status";
String json = "{}";
jsonWriteStr(json, "status", String(voltage));
String MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsV.key + "' data: " + String(voltage));
eventGen2(_paramsA.key, String(current));
jsonWriteStr(configLiveJson, _paramsA.key, String(current));
publishStatus(_paramsA.key, String(current));
path = mqttRootDevice + "/" +_paramsA.key + "/status";
json = "{}";
jsonWriteStr(json, "status", String(current));
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsA.key + "' data: " + String(current));
eventGen2(_paramsWatt.key, String(power));
jsonWriteStr(configLiveJson, _paramsWatt.key, String(power));
publishStatus(_paramsWatt.key, String(power));
path = mqttRootDevice + "/" +_paramsWatt.key + "/status";
json = "{}";
jsonWriteStr(json, "status", String(power));
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsWatt.key + "' data: " + String(power));
eventGen2(_paramsWattHrs.key, String(energy));
jsonWriteStr(configLiveJson, _paramsWattHrs.key, String(energy));
publishStatus(_paramsWattHrs.key, String(energy));
path = mqttRootDevice + "/" +_paramsWattHrs.key + "/status";
json = "{}";
jsonWriteStr(json, "status", String(energy));
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsWattHrs.key + "' data: " + String(energy));
eventGen2(_paramsHz.key, String(freq));
jsonWriteStr(configLiveJson, _paramsHz.key, String(freq));
publishStatus(_paramsHz.key, String(freq));
path = mqttRootDevice + "/" +_paramsHz.key + "/status";
json = "{}";
jsonWriteStr(json, "status", String(freq));
MyJson = json;
jsonWriteStr(MyJson, "topic", path);
ws.textAll(MyJson);
SerialPrint("I", "Sensor", "'" + _paramsHz.key + "' data: " + String(freq));
} else {
SerialPrint("E", "Sensor PZEM", "Error, UART switched off");

Some files were not shown because too many files have changed in this diff Show More