mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 14:12:16 +03:00
тест
This commit is contained in:
@@ -276,58 +276,7 @@
|
||||
"num": 20
|
||||
},
|
||||
{
|
||||
"name": "21. Частотомер на ADC, Частота",
|
||||
"type": "Reading",
|
||||
"subtype": "FreqMeterF",
|
||||
"id": "freq",
|
||||
"widget": "anydataHtz",
|
||||
"page": "Частотомер",
|
||||
"descr": "Частота",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 1,
|
||||
"pin-Esp32": 33,
|
||||
"samples": 512,
|
||||
"samplingFrequency": 5000,
|
||||
"int": 5,
|
||||
"num": 21
|
||||
},
|
||||
{
|
||||
"name": "22. Частотомер на ADC, Процент Пульсации",
|
||||
"type": "Reading",
|
||||
"subtype": "FreqMeterPcFl",
|
||||
"id": "pctFlicker",
|
||||
"widget": "anydataPct",
|
||||
"page": "Частотомер",
|
||||
"descr": "Процент Пульсации",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 1,
|
||||
"pin-Esp32": 33,
|
||||
"samples": 512,
|
||||
"samplingFrequency": 5000,
|
||||
"int": 5,
|
||||
"num": 22
|
||||
},
|
||||
{
|
||||
"name": "23. Частотомер на ADC, Индекс Пульсации",
|
||||
"type": "Reading",
|
||||
"subtype": "FreqMeterFlIn",
|
||||
"id": "flickerIndex",
|
||||
"widget": "anydataDef",
|
||||
"page": "Частотомер",
|
||||
"descr": "Индекс Пульсации",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 10,
|
||||
"pin-Esp32": 33,
|
||||
"samples": 512,
|
||||
"samplingFrequency": 5000,
|
||||
"int": 5,
|
||||
"num": 23
|
||||
},
|
||||
{
|
||||
"name": "24. GY21 Температура",
|
||||
"name": "21. GY21 Температура",
|
||||
"type": "Reading",
|
||||
"subtype": "GY21t",
|
||||
"id": "tmp4",
|
||||
@@ -336,10 +285,10 @@
|
||||
"descr": "Температура",
|
||||
"round": 1,
|
||||
"int": 15,
|
||||
"num": 24
|
||||
"num": 21
|
||||
},
|
||||
{
|
||||
"name": "25. GY21 Влажность",
|
||||
"name": "22. GY21 Влажность",
|
||||
"type": "Reading",
|
||||
"subtype": "GY21h",
|
||||
"id": "Hum4",
|
||||
@@ -348,10 +297,10 @@
|
||||
"descr": "Влажность",
|
||||
"round": 1,
|
||||
"int": 15,
|
||||
"num": 25
|
||||
"num": 22
|
||||
},
|
||||
{
|
||||
"name": "26. HDC1080 Температура",
|
||||
"name": "23. HDC1080 Температура",
|
||||
"type": "Reading",
|
||||
"subtype": "Hdc1080t",
|
||||
"id": "Temp1080",
|
||||
@@ -361,10 +310,10 @@
|
||||
"int": 15,
|
||||
"addr": "0x40",
|
||||
"round": 1,
|
||||
"num": 26
|
||||
"num": 23
|
||||
},
|
||||
{
|
||||
"name": "27. HDC1080 Влажность",
|
||||
"name": "24. HDC1080 Влажность",
|
||||
"type": "Reading",
|
||||
"subtype": "Hdc1080h",
|
||||
"id": "Hum1080",
|
||||
@@ -374,10 +323,10 @@
|
||||
"int": 15,
|
||||
"addr": "0x40",
|
||||
"round": 1,
|
||||
"num": 27
|
||||
"num": 24
|
||||
},
|
||||
{
|
||||
"name": "28. MAX6675 Температура",
|
||||
"name": "25. MAX6675 Температура",
|
||||
"type": "Reading",
|
||||
"subtype": "Max6675t",
|
||||
"id": "maxtmp",
|
||||
@@ -388,10 +337,10 @@
|
||||
"DO": 12,
|
||||
"CS": 13,
|
||||
"CLK": 14,
|
||||
"num": 28
|
||||
"num": 25
|
||||
},
|
||||
{
|
||||
"name": "29. PZEM 004t Напряжение",
|
||||
"name": "26. PZEM 004t Напряжение",
|
||||
"type": "Reading",
|
||||
"subtype": "Pzem004v",
|
||||
"id": "v",
|
||||
@@ -401,10 +350,10 @@
|
||||
"int": 15,
|
||||
"addr": "0xF8",
|
||||
"round": 1,
|
||||
"num": 29
|
||||
"num": 26
|
||||
},
|
||||
{
|
||||
"name": "30. PZEM 004t Сила тока",
|
||||
"name": "27. PZEM 004t Сила тока",
|
||||
"type": "Reading",
|
||||
"subtype": "Pzem004a",
|
||||
"id": "a",
|
||||
@@ -414,10 +363,10 @@
|
||||
"int": 15,
|
||||
"addr": "0xF8",
|
||||
"round": 1,
|
||||
"num": 30
|
||||
"num": 27
|
||||
},
|
||||
{
|
||||
"name": "31. PZEM 004t Мощность",
|
||||
"name": "28. PZEM 004t Мощность",
|
||||
"type": "Reading",
|
||||
"subtype": "Pzem004w",
|
||||
"id": "w",
|
||||
@@ -427,10 +376,10 @@
|
||||
"int": 15,
|
||||
"addr": "0xF8",
|
||||
"round": 1,
|
||||
"num": 31
|
||||
"num": 28
|
||||
},
|
||||
{
|
||||
"name": "32. PZEM 004t Энергия",
|
||||
"name": "29. PZEM 004t Энергия",
|
||||
"type": "Reading",
|
||||
"subtype": "Pzem004wh",
|
||||
"id": "wh",
|
||||
@@ -440,10 +389,10 @@
|
||||
"int": 15,
|
||||
"addr": "0xF8",
|
||||
"round": 1,
|
||||
"num": 32
|
||||
"num": 29
|
||||
},
|
||||
{
|
||||
"name": "33. PZEM 004t Частота",
|
||||
"name": "30. PZEM 004t Частота",
|
||||
"type": "Reading",
|
||||
"subtype": "Pzem004hz",
|
||||
"id": "hz",
|
||||
@@ -453,10 +402,10 @@
|
||||
"int": 15,
|
||||
"addr": "0xF8",
|
||||
"round": 1,
|
||||
"num": 33
|
||||
"num": 30
|
||||
},
|
||||
{
|
||||
"name": "34. PZEM 004t Косинус",
|
||||
"name": "31. PZEM 004t Косинус",
|
||||
"type": "Reading",
|
||||
"subtype": "Pzem004pf",
|
||||
"id": "pf",
|
||||
@@ -466,11 +415,11 @@
|
||||
"int": 15,
|
||||
"addr": "0xF8",
|
||||
"round": 1,
|
||||
"num": 34
|
||||
"num": 31
|
||||
},
|
||||
{
|
||||
"name": "35. Сканер кнопок 433 MHz",
|
||||
"num": 35,
|
||||
"name": "32. Сканер кнопок 433 MHz",
|
||||
"num": 32,
|
||||
"type": "Reading",
|
||||
"subtype": "RCswitch",
|
||||
"id": "rsw",
|
||||
@@ -479,7 +428,7 @@
|
||||
"pinTx": 12
|
||||
},
|
||||
{
|
||||
"name": "36. Sht20 Температура",
|
||||
"name": "33. Sht20 Температура",
|
||||
"type": "Reading",
|
||||
"subtype": "Sht20t",
|
||||
"id": "tmp2",
|
||||
@@ -488,10 +437,10 @@
|
||||
"descr": "Температура",
|
||||
"int": 15,
|
||||
"round": 1,
|
||||
"num": 36
|
||||
"num": 33
|
||||
},
|
||||
{
|
||||
"name": "37. Sht20 Влажность",
|
||||
"name": "34. Sht20 Влажность",
|
||||
"type": "Reading",
|
||||
"subtype": "Sht20h",
|
||||
"id": "Hum2",
|
||||
@@ -500,10 +449,10 @@
|
||||
"descr": "Влажность",
|
||||
"int": 15,
|
||||
"round": 1,
|
||||
"num": 37
|
||||
"num": 34
|
||||
},
|
||||
{
|
||||
"name": "38. Sht30 Температура",
|
||||
"name": "35. Sht30 Температура",
|
||||
"type": "Reading",
|
||||
"subtype": "Sht30t",
|
||||
"id": "tmp30",
|
||||
@@ -512,10 +461,10 @@
|
||||
"descr": "SHT30 Температура",
|
||||
"int": 15,
|
||||
"round": 1,
|
||||
"num": 38
|
||||
"num": 35
|
||||
},
|
||||
{
|
||||
"name": "39. Sht30 Влажность",
|
||||
"name": "36. Sht30 Влажность",
|
||||
"type": "Reading",
|
||||
"subtype": "Sht30h",
|
||||
"id": "Hum30",
|
||||
@@ -524,11 +473,11 @@
|
||||
"descr": "SHT30 Влажность",
|
||||
"int": 15,
|
||||
"round": 1,
|
||||
"num": 39
|
||||
"num": 36
|
||||
},
|
||||
{
|
||||
"name": "40. HC-SR04 Ультразвуковой дальномер",
|
||||
"num": 40,
|
||||
"name": "37. HC-SR04 Ультразвуковой дальномер",
|
||||
"num": 37,
|
||||
"type": "Reading",
|
||||
"subtype": "Sonar",
|
||||
"id": "sonar",
|
||||
@@ -540,7 +489,7 @@
|
||||
"int": 5
|
||||
},
|
||||
{
|
||||
"name": "41. UART",
|
||||
"name": "38. UART",
|
||||
"type": "Reading",
|
||||
"subtype": "UART",
|
||||
"page": "",
|
||||
@@ -550,13 +499,13 @@
|
||||
"tx": 12,
|
||||
"rx": 13,
|
||||
"speed": 9600,
|
||||
"num": 41
|
||||
"num": 38
|
||||
},
|
||||
{
|
||||
"header": "Исполнительные устройства"
|
||||
},
|
||||
{
|
||||
"name": "42. Кнопка подключенная к пину",
|
||||
"name": "39. Кнопка подключенная к пину",
|
||||
"type": "Writing",
|
||||
"subtype": "ButtonIn",
|
||||
"id": "btn",
|
||||
@@ -569,10 +518,10 @@
|
||||
"pinMode": "INPUT",
|
||||
"debounceDelay": 50,
|
||||
"fixState": 0,
|
||||
"num": 42
|
||||
"num": 39
|
||||
},
|
||||
{
|
||||
"name": "43. Управление пином",
|
||||
"name": "40. Управление пином",
|
||||
"type": "Writing",
|
||||
"subtype": "ButtonOut",
|
||||
"id": "btn",
|
||||
@@ -582,10 +531,10 @@
|
||||
"int": 0,
|
||||
"inv": 0,
|
||||
"pin": 2,
|
||||
"num": 43
|
||||
"num": 40
|
||||
},
|
||||
{
|
||||
"name": "44. Сервопривод",
|
||||
"name": "41. Сервопривод",
|
||||
"type": "Writing",
|
||||
"subtype": "IoTServo",
|
||||
"id": "servo",
|
||||
@@ -596,10 +545,10 @@
|
||||
"pin": 12,
|
||||
"apin": -1,
|
||||
"amap": "0, 4096, 0, 180",
|
||||
"num": 44
|
||||
"num": 41
|
||||
},
|
||||
{
|
||||
"name": "45. Расширитель портов Mcp23017",
|
||||
"name": "42. Расширитель портов Mcp23017",
|
||||
"type": "Reading",
|
||||
"subtype": "Mcp23017",
|
||||
"id": "Mcp",
|
||||
@@ -609,10 +558,10 @@
|
||||
"int": "0",
|
||||
"addr": "0x20",
|
||||
"index": 1,
|
||||
"num": 45
|
||||
"num": 42
|
||||
},
|
||||
{
|
||||
"name": "46. MP3 плеер",
|
||||
"name": "43. MP3 плеер",
|
||||
"type": "Reading",
|
||||
"subtype": "Mp3",
|
||||
"id": "mp3",
|
||||
@@ -622,10 +571,10 @@
|
||||
"int": 1,
|
||||
"pins": "14,12",
|
||||
"volume": 20,
|
||||
"num": 46
|
||||
"num": 43
|
||||
},
|
||||
{
|
||||
"name": "47. Расширитель портов Pcf8574",
|
||||
"name": "44. Расширитель портов Pcf8574",
|
||||
"type": "Reading",
|
||||
"subtype": "Pcf8574",
|
||||
"id": "Pcf",
|
||||
@@ -635,10 +584,10 @@
|
||||
"int": "0",
|
||||
"addr": "0x20",
|
||||
"index": 1,
|
||||
"num": 47
|
||||
"num": 44
|
||||
},
|
||||
{
|
||||
"name": "48. PWM ESP8266",
|
||||
"name": "45. PWM ESP8266",
|
||||
"type": "Writing",
|
||||
"subtype": "Pwm8266",
|
||||
"id": "pwm",
|
||||
@@ -650,10 +599,10 @@
|
||||
"freq": 5000,
|
||||
"val": 0,
|
||||
"apin": -1,
|
||||
"num": 48
|
||||
"num": 45
|
||||
},
|
||||
{
|
||||
"name": "49. Телеграм-Лайт",
|
||||
"name": "46. Телеграм-Лайт",
|
||||
"type": "Writing",
|
||||
"subtype": "TelegramLT",
|
||||
"id": "tg",
|
||||
@@ -662,13 +611,13 @@
|
||||
"descr": "",
|
||||
"token": "",
|
||||
"chatID": "",
|
||||
"num": 49
|
||||
"num": 46
|
||||
},
|
||||
{
|
||||
"header": "Экраны"
|
||||
},
|
||||
{
|
||||
"name": "50. LCD экран 2004",
|
||||
"name": "47. LCD экран 2004",
|
||||
"type": "Reading",
|
||||
"subtype": "Lcd2004",
|
||||
"id": "Lcd",
|
||||
@@ -680,10 +629,10 @@
|
||||
"size": "20,4",
|
||||
"coord": "0,0",
|
||||
"id2show": "id датчика",
|
||||
"num": 50
|
||||
"num": 47
|
||||
},
|
||||
{
|
||||
"name": "51. LCD экран 1602",
|
||||
"name": "48. LCD экран 1602",
|
||||
"type": "Reading",
|
||||
"subtype": "Lcd2004",
|
||||
"id": "Lcd",
|
||||
@@ -695,6 +644,6 @@
|
||||
"size": "16,2",
|
||||
"coord": "0,0",
|
||||
"id2show": "id датчика",
|
||||
"num": 51
|
||||
"num": 48
|
||||
}
|
||||
]
|
||||
@@ -247,7 +247,7 @@ bool WebSocketsServerCore::sendBIN(uint8_t num, const uint8_t * payload, size_t
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
* @return true if ok
|
||||
*/
|
||||
bool WebSocketsServerCore::broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload) {
|
||||
bool WebSocketsServerCore::broadcastBIN(uint8_t * payload, size_t length, bool fin, bool headerToPayload) {
|
||||
WSclient_t * client;
|
||||
bool ret = true;
|
||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||
|
||||
@@ -68,7 +68,7 @@ class WebSocketsServerCore : protected WebSockets {
|
||||
bool sendBIN(uint8_t num, uint8_t * payload, size_t length, bool fin = true, bool headerToPayload = false);
|
||||
bool sendBIN(uint8_t num, const uint8_t * payload, size_t length);
|
||||
|
||||
bool broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload = false);
|
||||
bool broadcastBIN(uint8_t * payload, size_t length, bool fin = true, bool headerToPayload = false);
|
||||
bool broadcastBIN(const uint8_t * payload, size_t length);
|
||||
|
||||
bool sendPing(uint8_t num, uint8_t * payload = NULL, size_t length = 0);
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/FreqMeter",
|
||||
"active": true
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/GY21",
|
||||
|
||||
@@ -9,7 +9,7 @@ board = nodemcuv2
|
||||
board_build.ldscript = eagle.flash.4m1m.ld
|
||||
platform = espressif8266 @4.0.1
|
||||
monitor_filters = esp8266_exception_decoder
|
||||
upload_speed = 115200
|
||||
upload_speed = 921600
|
||||
monitor_speed = 115200
|
||||
board_build.filesystem = littlefs
|
||||
build_src_filter =
|
||||
@@ -29,6 +29,7 @@ framework = arduino
|
||||
board = esp32dev
|
||||
platform = espressif32 @5.1.1
|
||||
monitor_filters = esp32_exception_decoder
|
||||
upload_speed = 921600
|
||||
monitor_speed = 115200
|
||||
debug_tool = esp-prog
|
||||
board_build.filesystem = littlefs
|
||||
@@ -56,11 +57,9 @@ lib_deps =
|
||||
adafruit/Adafruit BMP280 Library
|
||||
beegee-tokyo/DHT sensor library for ESPx
|
||||
milesburton/DallasTemperature@^3.9.1
|
||||
kosme/arduinoFFT@^1.5.6
|
||||
https://github.com/JonasGMorsch/GY-21.git
|
||||
ClosedCube HDC1080
|
||||
adafruit/MAX6675 library
|
||||
https://github.com/mandulaj/PZEM-004T-v30
|
||||
rc-switch @ ^2.6.4
|
||||
robtillaart/SHT2x@^0.1.1
|
||||
WEMOS SHT3x@1.0.0
|
||||
@@ -83,7 +82,6 @@ build_src_filter =
|
||||
+<modules/sensors/Bmp280>
|
||||
+<modules/sensors/Dht1122>
|
||||
+<modules/sensors/Ds18b20>
|
||||
+<modules/sensors/FreqMeter>
|
||||
+<modules/sensors/GY21>
|
||||
+<modules/sensors/Hdc1080>
|
||||
+<modules/sensors/Max6675>
|
||||
|
||||
@@ -181,10 +181,10 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length)
|
||||
// Страница веб интерфейса dev
|
||||
//----------------------------------------------------------------------//
|
||||
if (headerStr == "/dev|") {
|
||||
standWebSocket.sendTXT(num, errorsHeapJson);
|
||||
standWebSocket.sendTXT(num, settingsFlashJson);
|
||||
sendFileToWs("/config.json", num, 1024);
|
||||
sendFileToWs("/items.json", num, 1024);
|
||||
// standWebSocket.sendTXT(num, errorsHeapJson);
|
||||
// standWebSocket.sendTXT(num, settingsFlashJson);
|
||||
// sendFileToWs("/config.json", num, 1024);
|
||||
// sendFileToWs("/items.json", num, 1024);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
@@ -222,7 +222,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length)
|
||||
}
|
||||
|
||||
if (headerStr == "/test|") {
|
||||
sendBlobToWsStrHeader("/layout.json", "layout|0000|", num, 1024);
|
||||
sendBlobToWsStrHeader("/items.json", "layout|0000|", num, 2048);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -264,11 +264,11 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length)
|
||||
|
||||
//публикация статус сообщений (недостаток в том что делаем бродкаст всем клиентам поднятым в свелте!!!)
|
||||
void publishStatusWs(const String& topic, const String& data) {
|
||||
String path = mqttRootDevice + "/" + topic;
|
||||
String json = "{}";
|
||||
jsonWriteStr(json, "status", data);
|
||||
jsonWriteStr(json, "topic", path);
|
||||
standWebSocket.broadcastTXT(json);
|
||||
// String path = mqttRootDevice + "/" + topic;
|
||||
// String json = "{}";
|
||||
// jsonWriteStr(json, "status", data);
|
||||
// jsonWriteStr(json, "topic", path);
|
||||
// standWebSocket.broadcastTXT(json);
|
||||
}
|
||||
|
||||
//публикация статус сообщений
|
||||
@@ -292,9 +292,9 @@ void publishChartWs(int num, String& path) {
|
||||
|
||||
//данные которые мы отправляем в сокеты переодически
|
||||
void periodicWsSend() {
|
||||
standWebSocket.broadcastTXT(devListHeapJson);
|
||||
standWebSocket.broadcastTXT(ssidListHeapJson);
|
||||
standWebSocket.broadcastTXT(errorsHeapJson);
|
||||
// standWebSocket.broadcastTXT(devListHeapJson);
|
||||
// standWebSocket.broadcastTXT(ssidListHeapJson);
|
||||
// standWebSocket.broadcastTXT(errorsHeapJson);
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
@@ -427,14 +427,23 @@ void sendBlobToWsStrHeader(const String& filename, const String& header, uint8_t
|
||||
auto payloadBuf = &frameBuf[headerSize];
|
||||
// и сколько осталось места для нее
|
||||
auto maxPayloadSize = frameSize - headerSize;
|
||||
|
||||
int i = 0;
|
||||
while (file.available()) {
|
||||
// прочитаем кусок в буфер
|
||||
size_t payloadSize = file.read(payloadBuf, maxPayloadSize);
|
||||
if (payloadSize) {
|
||||
// отправим фрейм
|
||||
standWebSocket.sendBIN(client_id, frameBuf, headerSize + payloadSize, true);
|
||||
size_t size = headerSize + payloadSize;
|
||||
bool fin = false;
|
||||
if (i == 16) {
|
||||
fin = true;
|
||||
} else {
|
||||
fin = false;
|
||||
}
|
||||
|
||||
SerialPrint("I", "FS", String(size) + " " + String(fin) + " " + String(i));
|
||||
standWebSocket.sendBIN(client_id, frameBuf, size, fin);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ void* getAPI_Bme280(String subtype, String params);
|
||||
void* getAPI_Bmp280(String subtype, String params);
|
||||
void* getAPI_Dht1122(String subtype, String params);
|
||||
void* getAPI_Ds18b20(String subtype, String params);
|
||||
void* getAPI_FreqMeter(String subtype, String params);
|
||||
void* getAPI_GY21(String subtype, String params);
|
||||
void* getAPI_Hdc1080(String subtype, String params);
|
||||
void* getAPI_Max6675(String subtype, String params);
|
||||
@@ -46,7 +45,6 @@ if ((tmpAPI = getAPI_Bme280(subtype, params)) != nullptr) return tmpAPI;
|
||||
if ((tmpAPI = getAPI_Bmp280(subtype, params)) != nullptr) return tmpAPI;
|
||||
if ((tmpAPI = getAPI_Dht1122(subtype, params)) != nullptr) return tmpAPI;
|
||||
if ((tmpAPI = getAPI_Ds18b20(subtype, params)) != nullptr) return tmpAPI;
|
||||
if ((tmpAPI = getAPI_FreqMeter(subtype, params)) != nullptr) return tmpAPI;
|
||||
if ((tmpAPI = getAPI_GY21(subtype, params)) != nullptr) return tmpAPI;
|
||||
if ((tmpAPI = getAPI_Hdc1080(subtype, params)) != nullptr) return tmpAPI;
|
||||
if ((tmpAPI = getAPI_Max6675(subtype, params)) != nullptr) return tmpAPI;
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
"defActive": true,
|
||||
"defActive": false,
|
||||
"usedLibs": {
|
||||
"esp32_4mb": [
|
||||
"kosme/arduinoFFT@^1.5.6"
|
||||
|
||||
Reference in New Issue
Block a user