Compare commits

...

2 Commits

Author SHA1 Message Date
kkira
b0b832055e Доработка приложения 2026-06-16 22:26:33 +03:00
kkira
405a93bcae Оформление внешнего интерфейса 2026-05-28 20:20:58 +03:00
3 changed files with 568 additions and 225 deletions

View File

@@ -9,7 +9,7 @@
#include <Adafruit_NeoPixel.h>
// WIFI
const char* ssid = "Cathouse";
const char* ssid = "SinceCats";
const char* password = "88888888";
// CAMERA PINS

View File

@@ -6,6 +6,8 @@
#include <Wire.h>
#include <BH1750.h>
#include <ESP32Servo.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
BH1750 lightMeter;
@@ -13,21 +15,22 @@ BH1750 lightMeter;
float temperature = 0;
float humidity = 0;
float lux = 0;
String mqttStatus = "WAIT";
bool autoMode = false; // false = MANUAL
bool isNight = false;
String currentMode = "MANUAL";
WiFiClient espClient;
PubSubClient client(espClient);
const char* mqtt_server = "192.168.31.78";
const char* mqtt_server = "172.20.10.11";
// WIFI
const char* ssid = "Cathouse";
const char* ssid = "SinceCats";
const char* password = "88888888";
IPAddress local_IP(192,168,31,235);
IPAddress gateway(192,168,31,1);
IPAddress subnet(255,255,255,0);
IPAddress dns(192,168,31,1);
// CAMERA PINS
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
@@ -49,6 +52,17 @@ IPAddress dns(192,168,31,1);
#define HREF_GPIO_NUM 7
#define PCLK_GPIO_NUM 13
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(
SCREEN_WIDTH,
SCREEN_HEIGHT,
&Wire,
-1
);
// HTTP SERVER
httpd_handle_t server = NULL;
@@ -249,37 +263,57 @@ void setup()
{
Serial.begin(115200);
delay(1500);
Serial.println("\n\n=== ESP32-S3-CAM START ===");
Serial.println("Init Camera...");
if (!initCamera())
{
Serial.println("Camera init FAIL!");
delay(3000);
ESP.restart();
}
Serial.println("Camera init DONE");
WiFi.config(local_IP, gateway, subnet, dns);
Serial.println("Connecting WiFi...");
WiFi.begin(ssid, password);
WiFi.setSleep(false);
while (WiFi.status() != WL_CONNECTED)
{
delay(300);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 40) {
delay(500);
Serial.print(".");
attempts++;
}
Serial.println("\nWIFI OK");
Serial.println(WiFi.localIP());
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWIFI OK");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nWIFI FAIL");
}
Wire.begin(1, 2);
Wire.setClock(100000);
lightMeter.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{
Serial.println("OLED FAIL");
}
else
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
}
client.setServer(mqtt_server, 1883);
startServer();
Serial.println("STREAM READY:");
Serial.println("http://192.168.31.235/stream");
Serial.println("http://172.20.10.2/stream");
strip.begin();
strip.show();
@@ -297,10 +331,13 @@ void connectMQTT() {
String id = "ESP32CAM-" + String(WiFi.macAddress());
if (client.connect(id.c_str())) {
mqttStatus = "OK";
Serial.println("MQTT OK");
client.subscribe("esp32/led");
client.subscribe("esp32/servo");
client.subscribe("esp32/mode");
} else {
mqttStatus = "FAIL";
Serial.println("MQTT FAIL");
delay(2000);
}
@@ -355,7 +392,26 @@ void callback(char* topic, byte* payload, unsigned int length)
Serial.print("MQTT: ");
Serial.println(msg);
if (String(topic) == "esp32/led"){
if (String(topic) == "esp32/mode")
{
if (msg == "AUTO")
{
autoMode = true;
currentMode = "AUTO";
Serial.println("AUTO MODE");
}
if (msg == "MANUAL")
{
autoMode = false;
currentMode = "MANUAL";
setColor(0, 0, 0);
Serial.println("MANUAL MODE");
}
}
if (String(topic) == "esp32/led" && !autoMode){
if (msg == "OFF"){
setColor(0,0,0);
return;
@@ -365,7 +421,7 @@ void callback(char* topic, byte* payload, unsigned int length)
setColor(r,g,b);
}
if (String(topic) == "esp32/servo")
if (String(topic) == "esp32/servo" && !autoMode)
{
// ДЕНЬ
if (msg == "DAY"){
@@ -384,6 +440,35 @@ void callback(char* topic, byte* payload, unsigned int length)
}
}
void updateOLED(float lux)
{
display.clearDisplay();
display.setCursor(0,0);
display.print("Light: ");
display.print((int)lux);
display.println(" lx");
display.print("Temp: ");
display.print(temperature,1);
display.println(" C");
display.print("Hum : ");
display.print(humidity,1);
display.println(" %");
display.println();
display.print("MQTT: ");
display.println(mqttStatus);
display.print("MODE: ");
display.println(currentMode);
display.display();
}
void loop()
{
if (!client.connected())
@@ -392,15 +477,44 @@ void loop()
client.loop();
static unsigned long lastMQTT = 0;
static unsigned long lastOLED = 0;
// Датчики + MQTT каждые 5 секунд
if (millis() - lastMQTT > 5000)
{
lastMQTT = millis();
float lux = lightMeter.readLightLevel();
lux = lightMeter.readLightLevel();
readAHT20(temperature, humidity);
if (autoMode)
{
// НОЧЬ
if (lux < 200 && !isNight)
{
isNight = true;
servoLeft(5000);
setColor(0,0,40);
Serial.println("AUTO NIGHT");
}
// ДЕНЬ
if (lux >= 200 && isNight)
{
isNight = false;
servoRight(5000);
setColor(40,25,10);
Serial.println("AUTO DAY");
}
}
char buf[32];
snprintf(buf, sizeof(buf), "%.2f", lux);
@@ -424,5 +538,12 @@ void loop()
Serial.println(humidity);
}
// OLED раз в секунду
if (millis() - lastOLED > 1000)
{
lastOLED = millis();
updateOLED(lux);
}
vTaskDelay(2);
}

View File

@@ -1,16 +1,16 @@
[
{
"id": "b6a554cb58b20b89",
"id": "b54441ff0e1e1d78",
"type": "tab",
"label": "Поток 1",
"label": "Умная клетка для птиц",
"disabled": false,
"info": "",
"env": []
},
{
"id": "e2dbb550ecc754bb",
"id": "3329b02ba68d5122",
"type": "mqtt in",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "",
"topic": "Bird",
"qos": "2",
@@ -20,104 +20,85 @@
"rap": true,
"rh": 0,
"inputs": 0,
"x": 230,
"y": 300,
"x": 250,
"y": 260,
"wires": [
[
"2362125992f2f15a",
"853c51250983534e"
"69ab35d16ddcd908"
]
]
},
{
"id": "2362125992f2f15a",
"type": "debug",
"z": "b6a554cb58b20b89",
"name": "debug 1",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 440,
"y": 240,
"wires": []
},
{
"id": "853c51250983534e",
"id": "69ab35d16ddcd908",
"type": "ui_template",
"z": "b6a554cb58b20b89",
"group": "de858d4f14ceb677",
"name": "",
"order": 0,
"width": 0,
"height": 0,
"z": "b54441ff0e1e1d78",
"group": "546b157844234b18",
"name": "Video",
"order": 1,
"width": 6,
"height": 5,
"format": "<div id=\"camera-container\">\n <img id=\"camera-stream\" src=\"http://192.168.31.235/stream\"\n onerror=\"this.onerror=null; this.src='data:image/svg+xml,%3Csvg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"100%25\\\" height=\\\"400\\\"%3E%3Crect width=\\\"100%25\\\" height=\\\"100%25\\\" fill=\\\"%23333\\\"%3E%3C/rect%3E%3Ctext x=\\\"50%25\\\" y=\\\"50%25\\\" text-anchor=\\\"middle\\\" fill=\\\"%23fff\\\"%3ECamera offline - check connection%3C/text%3E%3C/svg%3E';\"\n style=\"width:100%; max-width:320px; height:240px;\">\n</div>\n\n<script>\n setInterval(function() {\n var img = document.getElementById('camera-stream');\n if (img) {\n var timestamp = new Date().getTime();\n img.src = 'http://192.168.31.235/stream?' + timestamp;\n }\n}, 5000);\n</script>",
"storeOutMessages": true,
"fwdInMessages": true,
"resendOnRefresh": true,
"templateScope": "local",
"className": "",
"x": 440,
"y": 300,
"x": 430,
"y": 260,
"wires": [
[]
]
},
{
"id": "f43e5b2d6e86f54d",
"id": "7d8023c9457af7b3",
"type": "mqtt in",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "light",
"topic": "esp32/sensors/light",
"qos": "2",
"qos": "0",
"datatype": "auto-detect",
"broker": "77647757300a0f3b",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 230,
"y": 400,
"x": 250,
"y": 340,
"wires": [
[
"5f6b7a790ede5d26",
"744d0ca72a8e8df6"
"d343a20cb8cc4c3f",
"953e9b0817d7888a"
]
]
},
{
"id": "347db67a62c25780",
"id": "98a116d0b230fd5e",
"type": "mqtt in",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "temp",
"topic": "esp32/sensors/temp",
"qos": "2",
"qos": "0",
"datatype": "auto-detect",
"broker": "77647757300a0f3b",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 230,
"y": 520,
"x": 250,
"y": 420,
"wires": [
[
"1abf7819982867cb",
"bade5e5c2073894d"
"967917ac6800fba7"
]
]
},
{
"id": "edacc7ae819555c1",
"id": "9f71a077937ffa10",
"type": "mqtt in",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "humidity",
"topic": "esp32/sensors/humidity",
"qos": "2",
"qos": "0",
"datatype": "auto-detect",
"broker": "77647757300a0f3b",
"nl": false,
@@ -125,130 +106,80 @@
"rh": 0,
"inputs": 0,
"x": 240,
"y": 660,
"y": 500,
"wires": [
[
"56ccdbc50d6e0d65",
"dc38d7ae67c9b0fa"
"a62bb5aa0c518728"
]
]
},
{
"id": "5f6b7a790ede5d26",
"type": "debug",
"z": "b6a554cb58b20b89",
"name": "debug 2",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 440,
"y": 400,
"wires": []
},
{
"id": "1abf7819982867cb",
"type": "debug",
"z": "b6a554cb58b20b89",
"name": "debug 3",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 440,
"y": 520,
"wires": []
},
{
"id": "56ccdbc50d6e0d65",
"type": "debug",
"z": "b6a554cb58b20b89",
"name": "debug 4",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 440,
"y": 660,
"wires": []
},
{
"id": "744d0ca72a8e8df6",
"id": "d343a20cb8cc4c3f",
"type": "ui_text",
"z": "b6a554cb58b20b89",
"group": "de858d4f14ceb677",
"order": 1,
"width": 0,
"height": 0,
"name": "",
"z": "b54441ff0e1e1d78",
"group": "546b157844234b18",
"order": 20,
"width": 4,
"height": 1,
"name": "Light",
"label": "Освещённость",
"format": "{{msg.payload}}",
"layout": "row-left",
"format": "{{msg.payload}} lux",
"layout": "row-spread",
"className": "",
"style": false,
"font": "",
"fontSize": 16,
"color": "#000000",
"x": 460,
"y": 360,
"x": 430,
"y": 340,
"wires": []
},
{
"id": "bade5e5c2073894d",
"id": "967917ac6800fba7",
"type": "ui_text",
"z": "b6a554cb58b20b89",
"group": "de858d4f14ceb677",
"order": 2,
"width": 0,
"height": 0,
"name": "",
"z": "b54441ff0e1e1d78",
"group": "546b157844234b18",
"order": 23,
"width": 4,
"height": 1,
"name": "Temperature",
"label": "Температура",
"format": "{{msg.payload}}",
"layout": "row-left",
"className": "",
"style": false,
"font": "",
"fontSize": 16,
"color": "#000000",
"x": 460,
"y": 480,
"wires": []
},
{
"id": "dc38d7ae67c9b0fa",
"type": "ui_text",
"z": "b6a554cb58b20b89",
"group": "de858d4f14ceb677",
"order": 3,
"width": 0,
"height": 0,
"name": "",
"label": "Влажность",
"format": "{{msg.payload}}",
"layout": "row-left",
"format": "{{msg.payload}} °C",
"layout": "row-spread",
"className": "",
"style": false,
"font": "",
"fontSize": 16,
"color": "#000000",
"x": 450,
"y": 620,
"y": 420,
"wires": []
},
{
"id": "0eacb49f1c0dd21a",
"id": "a62bb5aa0c518728",
"type": "ui_text",
"z": "b54441ff0e1e1d78",
"group": "546b157844234b18",
"order": 26,
"width": 4,
"height": 1,
"name": "Humidity",
"label": "Влажность",
"format": "{{msg.payload}} %",
"layout": "row-spread",
"className": "",
"style": false,
"font": "",
"fontSize": 16,
"color": "#000000",
"x": 440,
"y": 500,
"wires": []
},
{
"id": "326e3d7cd0711c1a",
"type": "mqtt out",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "",
"topic": "esp32/led",
"qos": "",
@@ -259,17 +190,17 @@
"correl": "",
"expiry": "",
"broker": "77647757300a0f3b",
"x": 620,
"y": 780,
"x": 660,
"y": 860,
"wires": []
},
{
"id": "dff600700ba8712a",
"id": "688951172c116781",
"type": "ui_colour_picker",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "color_led",
"label": "Настроить освещение",
"group": "de858d4f14ceb677",
"label": "Цвет свечения",
"group": "546b157844234b18",
"format": "hex",
"outformat": "string",
"showSwatch": true,
@@ -280,25 +211,25 @@
"showLightness": true,
"square": "false",
"dynOutput": "false",
"order": 5,
"width": 0,
"height": 0,
"order": 10,
"width": 3,
"height": 1,
"passthru": true,
"topic": "topic",
"topicType": "msg",
"className": "",
"x": 200,
"y": 840,
"x": 240,
"y": 860,
"wires": [
[
"2095de04955e307f"
"debe9d9adfca0645"
]
]
},
{
"id": "2095de04955e307f",
"id": "debe9d9adfca0645",
"type": "function",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "function 1",
"func": "let hex = msg.payload;\n\nhex = hex.replace(\"#\", \"\");\n\nlet r = parseInt(hex.substring(0, 2), 16);\nlet g = parseInt(hex.substring(2, 4), 16);\nlet b = parseInt(hex.substring(4, 6), 16);\n\nmsg.payload = `${r},${g},${b}`;\n\nreturn msg;",
"outputs": 1,
@@ -307,25 +238,25 @@
"initialize": "",
"finalize": "",
"libs": [],
"x": 400,
"y": 840,
"x": 440,
"y": 860,
"wires": [
[
"0eacb49f1c0dd21a"
"326e3d7cd0711c1a"
]
]
},
{
"id": "38796c6012673ea3",
"id": "95c5b2f761fe6d30",
"type": "ui_switch",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "led",
"label": "Выкл./Вкл. освещение",
"tooltip": "",
"group": "de858d4f14ceb677",
"group": "546b157844234b18",
"order": 5,
"width": 0,
"height": 0,
"width": 3,
"height": 1,
"passthru": true,
"decouple": "false",
"topic": "esp32/led",
@@ -341,23 +272,24 @@
"offcolor": "",
"animate": false,
"className": "",
"x": 390,
"y": 780,
"x": 430,
"y": 800,
"wires": [
[
"0eacb49f1c0dd21a"
"326e3d7cd0711c1a",
"a7a8bbbba6048822"
]
]
},
{
"id": "56c329c92a8daa3a",
"id": "9dd1c7f2d5e42901",
"type": "ui_button",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "day",
"group": "de858d4f14ceb677",
"order": 6,
"width": 0,
"height": 0,
"group": "546b157844234b18",
"order": 7,
"width": 2,
"height": 1,
"passthru": false,
"label": "День",
"tooltip": "",
@@ -369,23 +301,24 @@
"payloadType": "str",
"topic": "esp32/servo",
"topicType": "msg",
"x": 390,
"y": 920,
"x": 430,
"y": 640,
"wires": [
[
"cb039d5711277422"
"aa0c521baa5be283",
"018bce1ef78ece19"
]
]
},
{
"id": "136ce072862c41f7",
"id": "3f8af190256a6358",
"type": "ui_button",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "night",
"group": "de858d4f14ceb677",
"order": 8,
"width": 0,
"height": 0,
"group": "546b157844234b18",
"order": 15,
"width": 2,
"height": 1,
"passthru": false,
"label": "Ночь",
"tooltip": "",
@@ -397,23 +330,24 @@
"payloadType": "str",
"topic": "esp32/servo",
"topicType": "msg",
"x": 390,
"y": 1000,
"x": 430,
"y": 720,
"wires": [
[
"cb039d5711277422"
"aa0c521baa5be283",
"018bce1ef78ece19"
]
]
},
{
"id": "39d131b72bf61cc5",
"id": "e1b2f26f37b43975",
"type": "ui_button",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "mid",
"group": "de858d4f14ceb677",
"order": 7,
"width": 0,
"height": 0,
"group": "546b157844234b18",
"order": 12,
"width": 2,
"height": 1,
"passthru": false,
"label": "Полдень",
"tooltip": "",
@@ -425,18 +359,19 @@
"payloadType": "str",
"topic": "esp32/servo",
"topicType": "msg",
"x": 390,
"y": 960,
"x": 430,
"y": 680,
"wires": [
[
"cb039d5711277422"
"aa0c521baa5be283",
"018bce1ef78ece19"
]
]
},
{
"id": "cb039d5711277422",
"id": "018bce1ef78ece19",
"type": "mqtt out",
"z": "b6a554cb58b20b89",
"z": "b54441ff0e1e1d78",
"name": "",
"topic": "esp32/servo",
"qos": "",
@@ -447,10 +382,296 @@
"correl": "",
"expiry": "",
"broker": "77647757300a0f3b",
"x": 610,
"y": 980,
"x": 670,
"y": 640,
"wires": []
},
{
"id": "c238963e4e433c07",
"type": "ui_text",
"z": "b54441ff0e1e1d78",
"group": "546b157844234b18",
"order": 3,
"width": 4,
"height": 2,
"name": "",
"label": "Состояние жалюзи",
"format": "{{msg.payload}}",
"layout": "col-center",
"className": "",
"style": false,
"font": "",
"fontSize": 16,
"color": "#000000",
"x": 860,
"y": 720,
"wires": []
},
{
"id": "aa0c521baa5be283",
"type": "function",
"z": "b54441ff0e1e1d78",
"name": "function 2",
"func": "let command = msg.payload;\n\nlet status_text = \"\";\nlet status_color = \"\";\n\nswitch(command) {\n case \"DAY\":\n status_text = \"День\";\n status_color = \"green\";\n break;\n case \"MID\":\n status_text = \"Полдень\";\n status_color = \"orange\";\n break;\n case \"NIGHT\":\n status_text = \"Ночь\";\n status_color = \"blue\";\n break;\n default:\n status_text = \"Неизвестное состояние\";\n status_color = \"gray\";\n}\n\nmsg.payload = command;\n\nlet status_msg = {\n payload: status_text,\n topic: \"esp32/servo\"\n};\n\nnode.send([\n [status_msg],\n [msg]\n]);",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 660,
"y": 720,
"wires": [
[
"c238963e4e433c07"
]
]
},
{
"id": "a7a8bbbba6048822",
"type": "function",
"z": "b54441ff0e1e1d78",
"name": "function 3",
"func": "let led_value = msg.payload;\n\nlet status_text = \"Освещение выключено\";\nlet status_color = \"\";\n\nif (led_value === \"255,255,255\" || led_value === \"ON\") {\n status_text = \"Освещение включено\";\n status_color = \"green\";\n} else if (led_value === \"OFF\") {\n status_text = \"Освещение выключено\";\n status_color = \"red\";\n} \n\nlet status_msg = {\n payload: status_text,\n color: status_color\n};\n\nnode.send([status_msg]);\n\nlet mqtt_msg = {\n payload: led_value,\n topic: \"esp32/led\"\n};\nnode.send([null, mqtt_msg]);",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 660,
"y": 800,
"wires": [
[
"935423913e479104"
]
]
},
{
"id": "935423913e479104",
"type": "ui_text",
"z": "b54441ff0e1e1d78",
"group": "546b157844234b18",
"order": 2,
"width": 5,
"height": 2,
"name": "",
"label": "Состояние освещения",
"format": "{{msg.payload}}",
"layout": "col-center",
"className": "",
"style": false,
"font": "",
"fontSize": 16,
"color": "#000000",
"x": 870,
"y": 800,
"wires": []
},
{
"id": "953e9b0817d7888a",
"type": "ui_chart",
"z": "b54441ff0e1e1d78",
"name": "",
"group": "546b157844234b18",
"order": 17,
"width": 9,
"height": 5,
"label": "Изменение освещённости",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "0",
"ymax": "500",
"removeOlder": "24",
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"useUTC": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"useDifferentColor": false,
"className": "",
"x": 640,
"y": 340,
"wires": [
[]
]
},
{
"id": "f7c54e9ed468ad03",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 4,
"width": 1,
"height": 1
},
{
"id": "06f9e525bae03d4f",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 6,
"width": 2,
"height": 1
},
{
"id": "7e39ac586ef75670",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 8,
"width": 1,
"height": 1
},
{
"id": "eebc2ead2bdc4713",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 9,
"width": 1,
"height": 1
},
{
"id": "60c5659493f5b1e3",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 11,
"width": 2,
"height": 1
},
{
"id": "8e200c90a6fe2612",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 13,
"width": 1,
"height": 1
},
{
"id": "13a88f7bf1f6b955",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 14,
"width": 6,
"height": 1
},
{
"id": "d8806707892c2923",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 16,
"width": 1,
"height": 1
},
{
"id": "9a9ebc45643a2504",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 18,
"width": 6,
"height": 1
},
{
"id": "5e37295a74a08a72",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 19,
"width": 1,
"height": 1
},
{
"id": "8d65bde5f5fe894d",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 21,
"width": 1,
"height": 1
},
{
"id": "089a1385b0933a72",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 22,
"width": 1,
"height": 1
},
{
"id": "8dad06acd8afbd47",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 24,
"width": 1,
"height": 1
},
{
"id": "f1d14ae70273a27f",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 25,
"width": 1,
"height": 1
},
{
"id": "2da5e779df30a880",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 27,
"width": 1,
"height": 1
},
{
"id": "98a43a6570fb548d",
"type": "ui_spacer",
"z": "b54441ff0e1e1d78",
"name": "spacer",
"group": "546b157844234b18",
"order": 28,
"width": 6,
"height": 1
},
{
"id": "77647757300a0f3b",
"type": "mqtt-broker",
@@ -483,13 +704,14 @@
"sessionExpiry": ""
},
{
"id": "de858d4f14ceb677",
"id": "546b157844234b18",
"type": "ui_group",
"name": "Default",
"z": "b54441ff0e1e1d78",
"name": "Мониторинг и управление",
"tab": "8e35d7697e7af77c",
"order": 1,
"disp": true,
"width": "24",
"width": 15,
"collapse": false,
"className": ""
},
@@ -502,7 +724,7 @@
"hidden": false
},
{
"id": "cfd15ff24e6ffc58",
"id": "d21957267aecd6fc",
"type": "global-config",
"env": [],
"modules": {