[DISC] Add ability to change Discovery Prefix via WebUI or via mosquitto_pub (#2007)
Add discovery_prefix change at runtime --------- Co-authored-by: Florian <1technophile@users.noreply.github.com>
This commit is contained in:
1 parent
36945dae42
commit
57fbca8f88
6 files changed
+57
-13
No files matched your search
+2
-1
@@ -85,11 +85,12 @@ build_flags = '-UMQTTsetMQTT'
|
|||||||
If the new connection fails the gateway will fallback to the previous connection.
|
If the new connection fails the gateway will fallback to the previous connection.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Change the MQTT main topic and or gateway name
|
## Change the MQTT main topic, discovery prefix, and or gateway name
|
||||||
```
|
```
|
||||||
mosquitto_pub -t "home/OpenMQTTGateway/commands/MQTTtoSYS/config" -m
|
mosquitto_pub -t "home/OpenMQTTGateway/commands/MQTTtoSYS/config" -m
|
||||||
'{
|
'{
|
||||||
"mqtt_topic": "topic/",
|
"mqtt_topic": "topic/",
|
||||||
|
"discovery_prefix": "prefix",
|
||||||
"gateway_name": "name"
|
"gateway_name": "name"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ void announceDeviceTrigger(bool use_gateway_info, char* topic, char* type, char*
|
|||||||
sensor["device"] = device; //device representing the board
|
sensor["device"] = device; //device representing the board
|
||||||
|
|
||||||
/* Publish on the topic */
|
/* Publish on the topic */
|
||||||
String topic_to_publish = String(discovery_Topic) + "/device_automation/" + String(unique_id) + "/config";
|
String topic_to_publish = String(discovery_prefix) + "/device_automation/" + String(unique_id) + "/config";
|
||||||
Log.trace(F("Announce Device Trigger %s" CR), topic_to_publish.c_str());
|
Log.trace(F("Announce Device Trigger %s" CR), topic_to_publish.c_str());
|
||||||
pub_custom_topic((char*)topic_to_publish.c_str(), sensor, true);
|
pub_custom_topic((char*)topic_to_publish.c_str(), sensor, true);
|
||||||
}
|
}
|
||||||
@@ -434,7 +434,7 @@ void createDiscovery(const char* sensor_type,
|
|||||||
|
|
||||||
sensor["device"] = device;
|
sensor["device"] = device;
|
||||||
|
|
||||||
String topic = String(discovery_Topic) + "/" + String(sensor_type) + "/" + String(unique_id) + "/config";
|
String topic = String(discovery_prefix) + "/" + String(sensor_type) + "/" + String(unique_id) + "/config";
|
||||||
Log.trace(F("Announce Device %s on %s" CR), String(sensor_type).c_str(), topic.c_str());
|
Log.trace(F("Announce Device %s on %s" CR), String(sensor_type).c_str(), topic.c_str());
|
||||||
pub_custom_topic((char*)topic.c_str(), sensor, true);
|
pub_custom_topic((char*)topic.c_str(), sensor, true);
|
||||||
}
|
}
|
||||||
@@ -443,7 +443,7 @@ void eraseTopic(const char* sensor_type, const char* unique_id) {
|
|||||||
if (sensor_type == NULL || unique_id == NULL) {
|
if (sensor_type == NULL || unique_id == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String topic = String(discovery_Topic) + "/" + String(sensor_type) + "/" + String(unique_id) + "/config";
|
String topic = String(discovery_prefix) + "/" + String(sensor_type) + "/" + String(unique_id) + "/config";
|
||||||
Log.trace(F("Erase entity discovery %s on %s" CR), String(sensor_type).c_str(), topic.c_str());
|
Log.trace(F("Erase entity discovery %s on %s" CR), String(sensor_type).c_str(), topic.c_str());
|
||||||
pubMQTT((char*)topic.c_str(), "", true);
|
pubMQTT((char*)topic.c_str(), "", true);
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-2
@@ -692,7 +692,8 @@ void handleWI() {
|
|||||||
* T: handleMQ Arg: 4, sc=on
|
* T: handleMQ Arg: 4, sc=on
|
||||||
* T: handleMQ Arg: 5, h=
|
* T: handleMQ Arg: 5, h=
|
||||||
* T: handleMQ Arg: 6, mt=home/
|
* T: handleMQ Arg: 6, mt=home/
|
||||||
* T: handleMQ Arg: 7, save=
|
* T: handleMQ Arg: 7 dp=homeassistant (#ifdef ZmqttDiscovery)
|
||||||
|
* T: handleMQ Arg: 8, save=
|
||||||
*/
|
*/
|
||||||
void handleMQ() {
|
void handleMQ() {
|
||||||
WEBUI_TRACE_LOG(F("handleMQ: uri: %s, args: %d, method: %d" CR), server.uri(), server.args(), server.method());
|
WEBUI_TRACE_LOG(F("handleMQ: uri: %s, args: %d, method: %d" CR), server.uri(), server.args(), server.method());
|
||||||
@@ -762,6 +763,14 @@ void handleMQ() {
|
|||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# ifdef ZmqttDiscovery
|
||||||
|
if (server.hasArg("dp")) {
|
||||||
|
WEBtoSYS["discovery_prefix"] = server.arg("dp");
|
||||||
|
if (strncmp(discovery_prefix, server.arg("dp").c_str(), parameters_size)) {
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
# ifndef ESPWifiManualSetup
|
# ifndef ESPWifiManualSetup
|
||||||
if (update) {
|
if (update) {
|
||||||
@@ -803,11 +812,19 @@ void handleMQ() {
|
|||||||
String response = String(buffer);
|
String response = String(buffer);
|
||||||
response += String(script);
|
response += String(script);
|
||||||
response += String(style);
|
response += String(style);
|
||||||
// mqtt server (mh), mqtt port (ml), mqtt username (mu), mqtt password (mp), secure connection (sc), server certificate (msc), topic (mt)
|
// mqtt server (mh), mqtt port (ml), mqtt username (mu), mqtt password (mp), secure connection (sc), server certificate (msc), mqtt topic (mt), discovery prefix (dp) (last one only #ifdef ZmqttDiscovery)
|
||||||
# if MQTT_BROKER_MODE
|
# if MQTT_BROKER_MODE
|
||||||
|
# ifdef ZmqttDiscovery
|
||||||
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_mqtt_body, jsonChar, gateway_name, "", "1883", "", "", gateway_name, mqtt_topic, discovery_prefix);
|
||||||
|
# else
|
||||||
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_mqtt_body, jsonChar, gateway_name, "", "1883", "", "", gateway_name, mqtt_topic);
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_mqtt_body, jsonChar, gateway_name, "", "1883", "", "", gateway_name, mqtt_topic);
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
|
# ifdef ZmqttDiscovery
|
||||||
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_mqtt_body, jsonChar, gateway_name, cnt_parameters_array[CNT_DEFAULT_INDEX].mqtt_server, cnt_parameters_array[CNT_DEFAULT_INDEX].mqtt_port, cnt_parameters_array[CNT_DEFAULT_INDEX].mqtt_user, (cnt_parameters_array[CNT_DEFAULT_INDEX].isConnectionSecure ? "checked" : ""), gateway_name, mqtt_topic, discovery_prefix);
|
||||||
|
# else
|
||||||
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_mqtt_body, jsonChar, gateway_name, cnt_parameters_array[CNT_DEFAULT_INDEX].mqtt_server, cnt_parameters_array[CNT_DEFAULT_INDEX].mqtt_port, cnt_parameters_array[CNT_DEFAULT_INDEX].mqtt_user, (cnt_parameters_array[CNT_DEFAULT_INDEX].isConnectionSecure ? "checked" : ""), gateway_name, mqtt_topic);
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_mqtt_body, jsonChar, gateway_name, cnt_parameters_array[CNT_DEFAULT_INDEX].mqtt_server, cnt_parameters_array[CNT_DEFAULT_INDEX].mqtt_port, cnt_parameters_array[CNT_DEFAULT_INDEX].mqtt_user, (cnt_parameters_array[CNT_DEFAULT_INDEX].isConnectionSecure ? "checked" : ""), gateway_name, mqtt_topic);
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
response += String(buffer);
|
response += String(buffer);
|
||||||
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION);
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION);
|
||||||
|
|||||||
@@ -100,11 +100,13 @@ const char information_body[] = body_header "<style>td {padding: 0px 5px;}</styl
|
|||||||
const char upgrade_body[] = body_header "<div id='f1' style='display:block;'><fieldset class=\"set1\"><legend><span><b>Upgrade by Web Server</b></span></legend><form method='get' action='up'><br><b>OTA URL</b><br><input id='o' placeholder=\"OTA_URL\" value=\"%s\"><br><br><button type='submit' class='button bgrn'>Start upgrade</button></form></fieldset><br><br><fieldset class=\"set1\"><legend><span><b>Upgrade to Level</b></span></legend><form method='get' action='up'><p><b>Level</b><br><select id='le'><option value='1'>Latest Release</option><option value='2'>Development</option></select></p><br><button type='submit' class='button bgrn'>Start upgrade</button></form></fieldset></div><div id='f2' style='display:none;text-align:center;'><b>Upload started ...</b></div><div id=but2d style=\"display: block;\"></div><p>" body_footer_main_menu;
|
const char upgrade_body[] = body_header "<div id='f1' style='display:block;'><fieldset class=\"set1\"><legend><span><b>Upgrade by Web Server</b></span></legend><form method='get' action='up'><br><b>OTA URL</b><br><input id='o' placeholder=\"OTA_URL\" value=\"%s\"><br><br><button type='submit' class='button bgrn'>Start upgrade</button></form></fieldset><br><br><fieldset class=\"set1\"><legend><span><b>Upgrade to Level</b></span></legend><form method='get' action='up'><p><b>Level</b><br><select id='le'><option value='1'>Latest Release</option><option value='2'>Development</option></select></p><br><button type='submit' class='button bgrn'>Start upgrade</button></form></fieldset></div><div id='f2' style='display:none;text-align:center;'><b>Upload started ...</b></div><div id=but2d style=\"display: block;\"></div><p>" body_footer_main_menu;
|
||||||
|
|
||||||
const char config_wifi_body[] = body_header "%s<br><div><a href='/wi?scan='><b>Scan for all WiFi Networks</b></a></div><br><fieldset class=\"set1\"><legend><span><b>WiFi Parameters</b></span></legend><form method='get' action='wi'><p><b>WiFi Network</b> () <br><input id='s1' placeholder=\"Type or Select your WiFi Network\" value=\"%s\"></p><p><label><b>WiFi Password</b></label><br><input id='p1' type='password' placeholder=\"Enter your WiFi Password\" ></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
const char config_wifi_body[] = body_header "%s<br><div><a href='/wi?scan='><b>Scan for all WiFi Networks</b></a></div><br><fieldset class=\"set1\"><legend><span><b>WiFi Parameters</b></span></legend><form method='get' action='wi'><p><b>WiFi Network</b> () <br><input id='s1' placeholder=\"Type or Select your WiFi Network\" value=\"%s\"></p><p><label><b>WiFi Password</b></label><br><input id='p1' type='password' placeholder=\"Enter your WiFi Password\" ></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
||||||
|
#ifdef ZmqttDiscovery
|
||||||
// mqtt server (mh), mqtt port (ml), mqtt username (mu), mqtt password (mp), secure connection (sc), server certificate (msc), topic (mt)
|
// mqtt server (mh), mqtt port (ml), mqtt username (mu), mqtt password (mp), secure connection (sc), server certificate (msc), mqtt topic (mt), discovery prefix (dp)
|
||||||
|
const char config_mqtt_body[] = body_header "<fieldset class=\"set1\"><legend><span><b>MQTT Parameters</b></span></legend><form method='get' action='mq'><p><b>MQTT Server</b><br><input id='mh' placeholder=" MQTT_SERVER " value='%s'></p><p><b>MQTT Port</b><br><input id='ml' placeholder=" MQTT_PORT " value='%s'></p><p><b>MQTT Username</b><br><input id='mu' placeholder=" MQTT_USER " value='%s'></p><p><label><b>MQTT Password</b></label><br><input id='mp' type='password' placeholder=\"Password\" ></p><p><b>MQTT Secure Connection</b><br><input id='sc' type='checkbox' %s></p><p><b>Gateway Name</b><br><input id='h' placeholder=" Gateway_Name " value=\"%s\"></p><p><b>MQTT Base Topic</b><br><input id='mt' placeholder='' value='%s'></p><p><b>MQTT Discovery Prefix</b><br><input id='dp' placeholder='' value='%s'></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
||||||
|
#else
|
||||||
|
// mqtt server (mh), mqtt port (ml), mqtt username (mu), mqtt password (mp), secure connection (sc), server certificate (msc), mqtt topic (mt)
|
||||||
const char config_mqtt_body[] = body_header "<fieldset class=\"set1\"><legend><span><b>MQTT Parameters</b></span></legend><form method='get' action='mq'><p><b>MQTT Server</b><br><input id='mh' placeholder=" MQTT_SERVER " value='%s'></p><p><b>MQTT Port</b><br><input id='ml' placeholder=" MQTT_PORT " value='%s'></p><p><b>MQTT Username</b><br><input id='mu' placeholder=" MQTT_USER " value='%s'></p><p><label><b>MQTT Password</b></label><br><input id='mp' type='password' placeholder=\"Password\" ></p><p><b>MQTT Secure Connection</b><br><input id='sc' type='checkbox' %s></p><p><b>Gateway Name</b><br><input id='h' placeholder=" Gateway_Name " value=\"%s\"></p><p><b>MQTT Base Topic</b><br><input id='mt' placeholder='' value='%s'></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
const char config_mqtt_body[] = body_header "<fieldset class=\"set1\"><legend><span><b>MQTT Parameters</b></span></legend><form method='get' action='mq'><p><b>MQTT Server</b><br><input id='mh' placeholder=" MQTT_SERVER " value='%s'></p><p><b>MQTT Port</b><br><input id='ml' placeholder=" MQTT_PORT " value='%s'></p><p><b>MQTT Username</b><br><input id='mu' placeholder=" MQTT_USER " value='%s'></p><p><label><b>MQTT Password</b></label><br><input id='mp' type='password' placeholder=\"Password\" ></p><p><b>MQTT Secure Connection</b><br><input id='sc' type='checkbox' %s></p><p><b>Gateway Name</b><br><input id='h' placeholder=" Gateway_Name " value=\"%s\"></p><p><b>MQTT Base Topic</b><br><input id='mt' placeholder='' value='%s'></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
||||||
|
#endif
|
||||||
#ifndef ESPWifiManualSetup
|
#ifndef ESPWifiManualSetup
|
||||||
const char config_gateway_body[] = body_header "<fieldset class=\"set1\"><legend><span><b>Gateway Configuration</b></span></legend><form method='get' action='cg'><p><b>Gateway Password (8 characters min)</b><br><input id='gp' type='password' placeholder=\"********\" minlength='8'></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
const char config_gateway_body[] = body_header "<fieldset class=\"set1\"><legend><span><b>Gateway Configuration</b></span></legend><form method='get' action='cg'><p><b>Gateway Password (8 characters min)</b><br><input id='gp' type='password' placeholder=\"********\" minlength='8'></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -112,9 +112,14 @@ void announceDeviceTrigger(bool use_gateway_info,
|
|||||||
char* device_model,
|
char* device_model,
|
||||||
char* device_mac);
|
char* device_mac);
|
||||||
|
|
||||||
#ifndef discovery_Topic
|
#ifdef discovery_Topic //Deprecated - use discovery_Prefix instead
|
||||||
# define discovery_Topic "homeassistant"
|
# define discovery_Prefix "homeassistant"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef discovery_Prefix
|
||||||
|
# define discovery_Prefix "homeassistant"
|
||||||
|
#endif
|
||||||
|
char discovery_prefix[parameters_size + 1] = discovery_Prefix;
|
||||||
|
|
||||||
// discovery_republish_on_reconnect false to publish discovery topics over MQTT only with first connect
|
// discovery_republish_on_reconnect false to publish discovery topics over MQTT only with first connect
|
||||||
// discovery_republish_on_reconnect true to always republish discovery topics over MQTT when connection is re-established
|
// discovery_republish_on_reconnect true to always republish discovery topics over MQTT when connection is re-established
|
||||||
#ifndef discovery_republish_on_reconnect
|
#ifndef discovery_republish_on_reconnect
|
||||||
|
|||||||
+20
-1
@@ -340,7 +340,7 @@ protected:
|
|||||||
// Whenever a client subscribes successfully to some topic, see if this is likely a subscription to a
|
// Whenever a client subscribes successfully to some topic, see if this is likely a subscription to a
|
||||||
// autodiscovery topic. If it is, fire handle_autodiscovery().
|
// autodiscovery topic. If it is, fire handle_autodiscovery().
|
||||||
const String pattern(topic);
|
const String pattern(topic);
|
||||||
const bool is_autodiscovery_subscription = (pattern == "#") || (pattern.startsWith(String(discovery_Topic) + "/"));
|
const bool is_autodiscovery_subscription = (pattern == "#") || (pattern.startsWith(String(discovery_prefix) + "/"));
|
||||||
if (is_autodiscovery_subscription)
|
if (is_autodiscovery_subscription)
|
||||||
handle_autodiscovery();
|
handle_autodiscovery();
|
||||||
}
|
}
|
||||||
@@ -1333,6 +1333,9 @@ void setup() {
|
|||||||
Log.trace(F("OpenMQTTGateway ip: %s" CR), WiFi.localIP().toString().c_str());
|
Log.trace(F("OpenMQTTGateway ip: %s" CR), WiFi.localIP().toString().c_str());
|
||||||
Log.trace(F("OpenMQTTGateway index %d" CR), cnt_index);
|
Log.trace(F("OpenMQTTGateway index %d" CR), cnt_index);
|
||||||
Log.trace(F("OpenMQTTGateway mqtt topic: %s" CR), mqtt_topic);
|
Log.trace(F("OpenMQTTGateway mqtt topic: %s" CR), mqtt_topic);
|
||||||
|
#ifdef ZmqttDiscovery
|
||||||
|
Log.trace(F("OpenMQTTGateway mqtt discovery prefix: %s" CR), discovery_prefix);
|
||||||
|
#endif
|
||||||
Log.trace(F("OpenMQTTGateway gateway name: %s" CR), gateway_name);
|
Log.trace(F("OpenMQTTGateway gateway name: %s" CR), gateway_name);
|
||||||
#if !MQTT_BROKER_MODE
|
#if !MQTT_BROKER_MODE
|
||||||
Log.trace(F("OpenMQTTGateway mqtt server: %s" CR), cnt_parameters_array[cnt_index].mqtt_server);
|
Log.trace(F("OpenMQTTGateway mqtt server: %s" CR), cnt_parameters_array[cnt_index].mqtt_server);
|
||||||
@@ -1913,6 +1916,9 @@ void saveConfig() {
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
json["mqtt_topic"] = mqtt_topic;
|
json["mqtt_topic"] = mqtt_topic;
|
||||||
|
# ifdef ZmqttDiscovery
|
||||||
|
json["discovery_prefix"] = discovery_prefix;
|
||||||
|
# endif
|
||||||
json["gateway_name"] = gateway_name;
|
json["gateway_name"] = gateway_name;
|
||||||
json["ota_pass"] = ota_pass;
|
json["ota_pass"] = ota_pass;
|
||||||
|
|
||||||
@@ -2041,6 +2047,10 @@ bool loadConfigFromFlash() {
|
|||||||
# endif
|
# endif
|
||||||
if (json.containsKey("mqtt_topic"))
|
if (json.containsKey("mqtt_topic"))
|
||||||
strcpy(mqtt_topic, json["mqtt_topic"]);
|
strcpy(mqtt_topic, json["mqtt_topic"]);
|
||||||
|
# ifdef ZmqttDiscovery
|
||||||
|
if (json.containsKey("discovery_prefix"))
|
||||||
|
strcpy(discovery_prefix, json["discovery_prefix"]);
|
||||||
|
# endif
|
||||||
if (json.containsKey("gateway_name"))
|
if (json.containsKey("gateway_name"))
|
||||||
strcpy(gateway_name, json["gateway_name"]);
|
strcpy(gateway_name, json["gateway_name"]);
|
||||||
if (json.containsKey("ota_pass")) {
|
if (json.containsKey("ota_pass")) {
|
||||||
@@ -3280,11 +3290,20 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((SYSdata.containsKey("mqtt_topic") && SYSdata["mqtt_topic"].is<char*>()) ||
|
if ((SYSdata.containsKey("mqtt_topic") && SYSdata["mqtt_topic"].is<char*>()) ||
|
||||||
|
#ifdef ZmqttDiscovery
|
||||||
|
(SYSdata.containsKey("discovery_prefix") && SYSdata["discovery_prefix"].is<char*>()) ||
|
||||||
|
#endif
|
||||||
(SYSdata.containsKey("gateway_name") && SYSdata["gateway_name"].is<char*>()) ||
|
(SYSdata.containsKey("gateway_name") && SYSdata["gateway_name"].is<char*>()) ||
|
||||||
(SYSdata.containsKey("gw_pass") && SYSdata["gw_pass"].is<char*>())) {
|
(SYSdata.containsKey("gw_pass") && SYSdata["gw_pass"].is<char*>())) {
|
||||||
if (SYSdata.containsKey("mqtt_topic")) {
|
if (SYSdata.containsKey("mqtt_topic")) {
|
||||||
strncpy(mqtt_topic, SYSdata["mqtt_topic"], parameters_size);
|
strncpy(mqtt_topic, SYSdata["mqtt_topic"], parameters_size);
|
||||||
}
|
}
|
||||||
|
#ifdef ZmqttDiscovery
|
||||||
|
if (SYSdata.containsKey("discovery_prefix")) {
|
||||||
|
strncpy(discovery_prefix, SYSdata["discovery_prefix"], parameters_size);
|
||||||
|
restartESP = true; //Need to reset so all devices get re-discovered & published to new discovery_prefix
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (SYSdata.containsKey("gateway_name")) {
|
if (SYSdata.containsKey("gateway_name")) {
|
||||||
strncpy(gateway_name, SYSdata["gateway_name"], parameters_size);
|
strncpy(gateway_name, SYSdata["gateway_name"], parameters_size);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user