mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-30 11:59:12 +03:00
добавляем функцию отправки сообщений в телеграм для дневного графика
This commit is contained in:
@@ -613,33 +613,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"global": 0,
|
"global": 0,
|
||||||
"name": "42. MySensorsGate",
|
"name": "42. Расширитель портов Pcf8574",
|
||||||
"type": "Reading",
|
|
||||||
"subtype": "MySensorsGate",
|
|
||||||
"id": "gt",
|
|
||||||
"widget": "nil",
|
|
||||||
"page": "",
|
|
||||||
"descr": "",
|
|
||||||
"num": 42
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"global": 0,
|
|
||||||
"name": "43. MySensorsNode",
|
|
||||||
"type": "Reading",
|
|
||||||
"subtype": "MySensorsNode",
|
|
||||||
"id": "n",
|
|
||||||
"widget": "anydataTmp",
|
|
||||||
"page": "MySensors",
|
|
||||||
"descr": "Температура",
|
|
||||||
"orange": 60,
|
|
||||||
"red": 120,
|
|
||||||
"offline": 180,
|
|
||||||
"round": 1,
|
|
||||||
"num": 43
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"global": 0,
|
|
||||||
"name": "44. Расширитель портов Pcf8574",
|
|
||||||
"type": "Reading",
|
"type": "Reading",
|
||||||
"subtype": "Pcf8574",
|
"subtype": "Pcf8574",
|
||||||
"id": "Pcf",
|
"id": "Pcf",
|
||||||
@@ -649,29 +623,27 @@
|
|||||||
"int": "0",
|
"int": "0",
|
||||||
"addr": "0x20",
|
"addr": "0x20",
|
||||||
"index": 1,
|
"index": 1,
|
||||||
"num": 44
|
"num": 42
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"global": 0,
|
"global": 0,
|
||||||
"name": "45. PWM ESP32",
|
"name": "43. PWM ESP8266",
|
||||||
"type": "Writing",
|
"type": "Writing",
|
||||||
"subtype": "Pwm32",
|
"subtype": "Pwm8266",
|
||||||
"id": "pwm",
|
"id": "pwm",
|
||||||
"widget": "range",
|
"widget": "range",
|
||||||
"page": "Кнопки",
|
"page": "Кнопки",
|
||||||
"descr": "PWM",
|
"descr": "PWM",
|
||||||
"int": 0,
|
"int": 0,
|
||||||
"pin": 2,
|
"pin": 15,
|
||||||
"freq": 5000,
|
"freq": 5000,
|
||||||
"ledChannel": 2,
|
|
||||||
"PWM_resolution": 10,
|
|
||||||
"val": 0,
|
"val": 0,
|
||||||
"apin": -1,
|
"apin": -1,
|
||||||
"num": 45
|
"num": 43
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"global": 0,
|
"global": 0,
|
||||||
"name": "46. Телеграм-Лайт",
|
"name": "44. Телеграм-Лайт",
|
||||||
"type": "Writing",
|
"type": "Writing",
|
||||||
"subtype": "TelegramLT",
|
"subtype": "TelegramLT",
|
||||||
"id": "tg",
|
"id": "tg",
|
||||||
@@ -680,14 +652,14 @@
|
|||||||
"descr": "",
|
"descr": "",
|
||||||
"token": "",
|
"token": "",
|
||||||
"chatID": "",
|
"chatID": "",
|
||||||
"num": 46
|
"num": 44
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"header": "Экраны"
|
"header": "Экраны"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"global": 0,
|
"global": 0,
|
||||||
"name": "47. LCD экран 2004",
|
"name": "45. LCD экран 2004",
|
||||||
"type": "Reading",
|
"type": "Reading",
|
||||||
"subtype": "Lcd2004",
|
"subtype": "Lcd2004",
|
||||||
"id": "Lcd",
|
"id": "Lcd",
|
||||||
@@ -699,10 +671,10 @@
|
|||||||
"size": "20,4",
|
"size": "20,4",
|
||||||
"coord": "0,0",
|
"coord": "0,0",
|
||||||
"id2show": "id датчика",
|
"id2show": "id датчика",
|
||||||
"num": 47
|
"num": 45
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "48. LCD экран 1602",
|
"name": "46. LCD экран 1602",
|
||||||
"type": "Reading",
|
"type": "Reading",
|
||||||
"subtype": "Lcd2004",
|
"subtype": "Lcd2004",
|
||||||
"id": "Lcd",
|
"id": "Lcd",
|
||||||
@@ -714,6 +686,6 @@
|
|||||||
"size": "16,2",
|
"size": "16,2",
|
||||||
"coord": "0,0",
|
"coord": "0,0",
|
||||||
"id2show": "id датчика",
|
"id2show": "id датчика",
|
||||||
"num": 48
|
"num": 46
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -56,6 +56,9 @@ class IoTItem {
|
|||||||
virtual void onMqttRecive(String& topic, String& msg);
|
virtual void onMqttRecive(String& topic, String& msg);
|
||||||
virtual void onMqttWsAppConnectEvent();
|
virtual void onMqttWsAppConnectEvent();
|
||||||
|
|
||||||
|
// делаем доступным модулям отправку сообщений в телеграм
|
||||||
|
virtual void sendTelegramMsg(bool often, String msg);
|
||||||
|
|
||||||
// методы для графиков (будет упрощено)
|
// методы для графиков (будет упрощено)
|
||||||
virtual void publishValue();
|
virtual void publishValue();
|
||||||
virtual void clearValue();
|
virtual void clearValue();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"projectProp": {
|
"projectProp": {
|
||||||
"platformio": {
|
"platformio": {
|
||||||
"default_envs": "esp32_4mb",
|
"default_envs": "esp8266_4mb",
|
||||||
"comments_default_envs": "choose from: esp8266_4mb or esp32_4mb or esp8266_1mb or esp8266_1mb_ota or esp8285_1mb or esp8285_1mb_ota"
|
"comments_default_envs": "choose from: esp8266_4mb or esp32_4mb or esp8266_1mb or esp8266_1mb_ota or esp8285_1mb or esp8285_1mb_ota"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[platformio]
|
[platformio]
|
||||||
default_envs = esp32_4mb
|
default_envs = esp8266_4mb
|
||||||
data_dir = data_svelte
|
data_dir = data_svelte
|
||||||
|
|
||||||
[common_env_data]
|
[common_env_data]
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ void IoTItem::regEvent(const String& value, const String& consoleInfo, bool erro
|
|||||||
(*it)->onRegEvent(this);
|
(*it)->onRegEvent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//отправка события другим устройствам в сети если не было ошибки==============================
|
// отправка события другим устройствам в сети если не было ошибки
|
||||||
if (jsonReadBool(settingsFlashJson, "mqttin") && _global && !error) {
|
if (jsonReadBool(settingsFlashJson, "mqttin") && _global && !error) {
|
||||||
String json = "{}";
|
String json = "{}";
|
||||||
jsonWriteStr_(json, "id", _id);
|
jsonWriteStr_(json, "id", _id);
|
||||||
@@ -179,6 +179,9 @@ void IoTItem::onRegEvent(IoTItem* item) {}
|
|||||||
void IoTItem::onMqttRecive(String& topic, String& msg) {}
|
void IoTItem::onMqttRecive(String& topic, String& msg) {}
|
||||||
void IoTItem::onMqttWsAppConnectEvent() {}
|
void IoTItem::onMqttWsAppConnectEvent() {}
|
||||||
|
|
||||||
|
// делаем доступным модулям отправку сообщений в телеграм
|
||||||
|
void IoTItem::sendTelegramMsg(bool often, String msg) {}
|
||||||
|
|
||||||
// методы для графиков (будет упрощено)
|
// методы для графиков (будет упрощено)
|
||||||
void IoTItem::publishValue() {}
|
void IoTItem::publishValue() {}
|
||||||
void IoTItem::clearValue() {}
|
void IoTItem::clearValue() {}
|
||||||
|
|||||||
@@ -24,9 +24,8 @@ void* getAPI_IoTServo(String subtype, String params);
|
|||||||
void* getAPI_Mcp23017(String subtype, String params);
|
void* getAPI_Mcp23017(String subtype, String params);
|
||||||
void* getAPI_Mp3(String subtype, String params);
|
void* getAPI_Mp3(String subtype, String params);
|
||||||
void* getAPI_Multitouch(String subtype, String params);
|
void* getAPI_Multitouch(String subtype, String params);
|
||||||
void* getAPI_MySensorsGate(String subtype, String params);
|
|
||||||
void* getAPI_Pcf8574(String subtype, String params);
|
void* getAPI_Pcf8574(String subtype, String params);
|
||||||
void* getAPI_Pwm32(String subtype, String params);
|
void* getAPI_Pwm8266(String subtype, String params);
|
||||||
void* getAPI_TelegramLT(String subtype, String params);
|
void* getAPI_TelegramLT(String subtype, String params);
|
||||||
void* getAPI_Lcd2004(String subtype, String params);
|
void* getAPI_Lcd2004(String subtype, String params);
|
||||||
|
|
||||||
@@ -56,9 +55,8 @@ if ((tmpAPI = getAPI_IoTServo(subtype, params)) != nullptr) return tmpAPI;
|
|||||||
if ((tmpAPI = getAPI_Mcp23017(subtype, params)) != nullptr) return tmpAPI;
|
if ((tmpAPI = getAPI_Mcp23017(subtype, params)) != nullptr) return tmpAPI;
|
||||||
if ((tmpAPI = getAPI_Mp3(subtype, params)) != nullptr) return tmpAPI;
|
if ((tmpAPI = getAPI_Mp3(subtype, params)) != nullptr) return tmpAPI;
|
||||||
if ((tmpAPI = getAPI_Multitouch(subtype, params)) != nullptr) return tmpAPI;
|
if ((tmpAPI = getAPI_Multitouch(subtype, params)) != nullptr) return tmpAPI;
|
||||||
if ((tmpAPI = getAPI_MySensorsGate(subtype, params)) != nullptr) return tmpAPI;
|
|
||||||
if ((tmpAPI = getAPI_Pcf8574(subtype, params)) != nullptr) return tmpAPI;
|
if ((tmpAPI = getAPI_Pcf8574(subtype, params)) != nullptr) return tmpAPI;
|
||||||
if ((tmpAPI = getAPI_Pwm32(subtype, params)) != nullptr) return tmpAPI;
|
if ((tmpAPI = getAPI_Pwm8266(subtype, params)) != nullptr) return tmpAPI;
|
||||||
if ((tmpAPI = getAPI_TelegramLT(subtype, params)) != nullptr) return tmpAPI;
|
if ((tmpAPI = getAPI_TelegramLT(subtype, params)) != nullptr) return tmpAPI;
|
||||||
if ((tmpAPI = getAPI_Lcd2004(subtype, params)) != nullptr) return tmpAPI;
|
if ((tmpAPI = getAPI_Lcd2004(subtype, params)) != nullptr) return tmpAPI;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -1,24 +1,19 @@
|
|||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
#include "classes/IoTItem.h"
|
#include "classes/IoTItem.h"
|
||||||
|
|
||||||
class TelegramLT : public IoTItem
|
class TelegramLT : public IoTItem {
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
String _prevMsg = "";
|
String _prevMsg = "";
|
||||||
String _token;
|
String _token;
|
||||||
String _chatID;
|
String _chatID;
|
||||||
|
|
||||||
TelegramLT(String parameters) : IoTItem(parameters)
|
TelegramLT(String parameters) : IoTItem(parameters) {
|
||||||
{
|
|
||||||
jsonRead(parameters, "token", _token);
|
jsonRead(parameters, "token", _token);
|
||||||
jsonRead(parameters, "chatID", _chatID);
|
jsonRead(parameters, "chatID", _chatID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendTelegramMsg(bool often, String msg)
|
void sendTelegramMsg(bool often, String msg) {
|
||||||
{
|
if (WiFi.status() == WL_CONNECTED && (often || !often && _prevMsg != msg)) {
|
||||||
if (WiFi.status() == WL_CONNECTED && (often || !often && _prevMsg != msg))
|
|
||||||
{
|
|
||||||
WiFiClient client;
|
WiFiClient client;
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
http.begin(client, "http://live-control.com/iotm/telegram.php");
|
http.begin(client, "http://live-control.com/iotm/telegram.php");
|
||||||
@@ -29,14 +24,11 @@ public:
|
|||||||
SerialPrint("<-", F("Telegram"), "chat ID: " + _chatID + ", msg: " + msg);
|
SerialPrint("<-", F("Telegram"), "chat ID: " + _chatID + ", msg: " + msg);
|
||||||
SerialPrint("->", F("Telegram"), "chat ID: " + _chatID + ", server: " + httpResponseCode);
|
SerialPrint("->", F("Telegram"), "chat ID: " + _chatID + ", server: " + httpResponseCode);
|
||||||
|
|
||||||
if (!strstr(payload.c_str(), "{\"ok\":true"))
|
if (!strstr(payload.c_str(), "{\"ok\":true")) {
|
||||||
{
|
|
||||||
value.valD = 0;
|
value.valD = 0;
|
||||||
Serial.printf("Telegram error, msg from server: %s\n", payload.c_str());
|
Serial.printf("Telegram error, msg from server: %s\n", payload.c_str());
|
||||||
regEvent(value.valD, payload);
|
regEvent(value.valD, payload);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
value.valD = 1;
|
value.valD = 1;
|
||||||
regEvent(value.valD, payload);
|
regEvent(value.valD, payload);
|
||||||
}
|
}
|
||||||
@@ -45,27 +37,20 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
IoTValue execute(String command, std::vector<IoTValue> ¶m) {
|
||||||
{
|
if (param.size() == 1) {
|
||||||
if (param.size() == 1)
|
|
||||||
{
|
|
||||||
String strTmp;
|
String strTmp;
|
||||||
if (param[0].isDecimal && param[0].valS == "")
|
if (param[0].isDecimal && param[0].valS == "")
|
||||||
strTmp = param[0].valD;
|
strTmp = param[0].valD;
|
||||||
else
|
else
|
||||||
strTmp = param[0].valS;
|
strTmp = param[0].valS;
|
||||||
|
|
||||||
if (command == "sendMsg")
|
if (command == "sendMsg") {
|
||||||
{
|
if (param.size()) {
|
||||||
if (param.size())
|
|
||||||
{
|
|
||||||
sendTelegramMsg(false, strTmp);
|
sendTelegramMsg(false, strTmp);
|
||||||
}
|
}
|
||||||
}
|
} else if (command == "sendOftenMsg") {
|
||||||
else if (command == "sendOftenMsg")
|
if (param.size()) {
|
||||||
{
|
|
||||||
if (param.size())
|
|
||||||
{
|
|
||||||
sendTelegramMsg(true, strTmp);
|
sendTelegramMsg(true, strTmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,14 +61,10 @@ public:
|
|||||||
~TelegramLT(){};
|
~TelegramLT(){};
|
||||||
};
|
};
|
||||||
|
|
||||||
void *getAPI_TelegramLT(String subtype, String param)
|
void *getAPI_TelegramLT(String subtype, String param) {
|
||||||
{
|
if (subtype == F("TelegramLT")) {
|
||||||
if (subtype == F("TelegramLT"))
|
|
||||||
{
|
|
||||||
return new TelegramLT(param);
|
return new TelegramLT(param);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,8 @@ class LogingDaily : public IoTItem {
|
|||||||
String id;
|
String id;
|
||||||
String filesList = "";
|
String filesList = "";
|
||||||
|
|
||||||
|
String descr;
|
||||||
|
|
||||||
int _publishType = -2;
|
int _publishType = -2;
|
||||||
int _wsNum = -1;
|
int _wsNum = -1;
|
||||||
|
|
||||||
@@ -16,6 +18,8 @@ class LogingDaily : public IoTItem {
|
|||||||
|
|
||||||
int testMode;
|
int testMode;
|
||||||
|
|
||||||
|
int telegram;
|
||||||
|
|
||||||
IoTItem *dateIoTItem;
|
IoTItem *dateIoTItem;
|
||||||
|
|
||||||
String prevDate = "";
|
String prevDate = "";
|
||||||
@@ -29,6 +33,8 @@ class LogingDaily : public IoTItem {
|
|||||||
jsonRead(parameters, F("id"), id);
|
jsonRead(parameters, F("id"), id);
|
||||||
jsonRead(parameters, F("points"), points);
|
jsonRead(parameters, F("points"), points);
|
||||||
jsonRead(parameters, F("test"), testMode);
|
jsonRead(parameters, F("test"), testMode);
|
||||||
|
jsonRead(parameters, F("telegram"), telegram);
|
||||||
|
jsonRead(parameters, F("descr"), descr);
|
||||||
|
|
||||||
if (points > 365) {
|
if (points > 365) {
|
||||||
points = 365;
|
points = 365;
|
||||||
@@ -61,7 +67,7 @@ class LogingDaily : public IoTItem {
|
|||||||
|
|
||||||
// если время не было получено из интернета
|
// если время не было получено из интернета
|
||||||
if (!isTimeSynch) {
|
if (!isTimeSynch) {
|
||||||
SerialPrint("E", F("LogingDaily"), "'" + id + "' Сant LogingDaily - time not synchronized, return");
|
SerialPrint("E", F("LogingDaily"), "'" + id + "' Cant LogingDaily - time not synchronized, return");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +81,15 @@ class LogingDaily : public IoTItem {
|
|||||||
|
|
||||||
float difference = currentValue - prevValue;
|
float difference = currentValue - prevValue;
|
||||||
|
|
||||||
|
if (telegram == 1) {
|
||||||
|
String msg = descr + " " + String(currentValue) + " " + String(difference);
|
||||||
|
for (std::list<IoTItem *>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) {
|
||||||
|
if ((*it)->getSubtype() == "TelegramLT" || "Telegram") {
|
||||||
|
(*it)->sendTelegramMsg(false, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jsonWriteInt(logData, "x", unixTime - 120);
|
jsonWriteInt(logData, "x", unixTime - 120);
|
||||||
jsonWriteFloat(logData, "y1", difference);
|
jsonWriteFloat(logData, "y1", difference);
|
||||||
|
|
||||||
@@ -108,18 +123,18 @@ class LogingDaily : public IoTItem {
|
|||||||
|
|
||||||
String path = "/lgd/" + id + "/" + id + ".txt"; // создадим путь вида /lgd/id/id.txt
|
String path = "/lgd/" + id + "/" + id + ".txt"; // создадим путь вида /lgd/id/id.txt
|
||||||
// создадим пустой файл
|
// создадим пустой файл
|
||||||
if (writeEmptyFile(path) != "sucсess") {
|
if (writeEmptyFile(path) != "success") {
|
||||||
SerialPrint("E", F("LogingDaily"), "'" + id + "' file writing error, return");
|
SerialPrint("E", F("LogingDaily"), "'" + id + "' file writing error, return");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// запишем в него данные
|
// запишем в него данные
|
||||||
if (addFile(path, logData) != "sucсess") {
|
if (addFile(path, logData) != "success") {
|
||||||
SerialPrint("E", F("LogingDaily"), "'" + id + "' data writing error, return");
|
SerialPrint("E", F("LogingDaily"), "'" + id + "' data writing error, return");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// запишем путь к нему в базу данных
|
// запишем путь к нему в базу данных
|
||||||
if (saveDataDB(id, path) != "sucсess") {
|
if (saveDataDB(id, path) != "success") {
|
||||||
SerialPrint("E", F("LogingDaily"), "'" + id + "' db file writing error, return");
|
SerialPrint("E", F("LogingDaily"), "'" + id + "' db file writing error, return");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -128,7 +143,7 @@ class LogingDaily : public IoTItem {
|
|||||||
|
|
||||||
void addNewDataToExistingFile(String &path, String &logData) {
|
void addNewDataToExistingFile(String &path, String &logData) {
|
||||||
logData = logData + ",";
|
logData = logData + ",";
|
||||||
if (addFile(path, logData) != "sucсess") {
|
if (addFile(path, logData) != "success") {
|
||||||
SerialPrint("i", F("LogingDaily"), "'" + id + "' file writing error, return");
|
SerialPrint("i", F("LogingDaily"), "'" + id + "' file writing error, return");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,8 @@
|
|||||||
"int": 1,
|
"int": 1,
|
||||||
"logid": "t",
|
"logid": "t",
|
||||||
"points": 365,
|
"points": 365,
|
||||||
"column": 0
|
"telegram": 0,
|
||||||
|
"test": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"about": {
|
"about": {
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
"authorGit": "https://github.com/DmitryBorisenko33",
|
"authorGit": "https://github.com/DmitryBorisenko33",
|
||||||
"specialThanks": "@itsid1 @Valiuhaaa Serg",
|
"specialThanks": "@itsid1 @Valiuhaaa Serg",
|
||||||
"moduleName": "LogingDaily",
|
"moduleName": "LogingDaily",
|
||||||
"moduleVersion": "3.0",
|
"moduleVersion": "3.1",
|
||||||
"usedRam": {
|
"usedRam": {
|
||||||
"esp32_4mb": 15,
|
"esp32_4mb": 15,
|
||||||
"esp8266_4mb": 15
|
"esp8266_4mb": 15
|
||||||
@@ -34,7 +35,8 @@
|
|||||||
"int": "Интервал логирования в мнутах, частота проверки смены суток в минутах. Не рекомендуется менять",
|
"int": "Интервал логирования в мнутах, частота проверки смены суток в минутах. Не рекомендуется менять",
|
||||||
"logid": "ID накопительной величины которую будем логировать",
|
"logid": "ID накопительной величины которую будем логировать",
|
||||||
"points": "Максимальное количество точек",
|
"points": "Максимальное количество точек",
|
||||||
"column": "Режим тестирования - график будет обновляться не раз в сутки, а кадый заданный в int интервал. Суточные столбики - 0, Минутные столбики - 1"
|
"telegram": "График будет отправлять в телеграм репорт с расходами каждый день",
|
||||||
|
"test": "Параметр необходим для разработчиков. Режим тестирования. График будет обновляться не раз в сутки, а кадый заданный в int интервал."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defActive": true,
|
"defActive": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user