Compare commits
8 Commits
v_1.2.2007.34
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| ffc45ff43a | |||
| 5639cf280b | |||
| 24100f7bb2 | |||
| 53d7b6cb8e | |||
| 72a38de46b | |||
| b61dedf3fa | |||
| 36f3b8f135 | |||
| 01d87a2191 |
@@ -1,73 +1,73 @@
|
||||
{
|
||||
"confPLC": {
|
||||
"ipAdrr": "192.168.0.51",
|
||||
"tipoCpu": "S7300",
|
||||
"rack": 0,
|
||||
"slot": 2
|
||||
},
|
||||
"triggerList": {
|
||||
"DB700.DBX0.0": {
|
||||
"Column": "Trigger",
|
||||
"MemConf": "DB700.DBX0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"TriggerVal": "True",
|
||||
"bitAdr": 0
|
||||
"confPLC": {
|
||||
"ipAdrr": "192.168.0.52",
|
||||
"tipoCpu": "S7300",
|
||||
"rack": 0,
|
||||
"slot": 2
|
||||
},
|
||||
"triggerList": {
|
||||
"DB700.DBX0.0": {
|
||||
"Column": "Trigger",
|
||||
"MemConf": "DB700.DBX0.0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"TriggerVal": "True",
|
||||
"bitAdr": 0
|
||||
}
|
||||
},
|
||||
"parametersList": {
|
||||
"DB700.DBX0.2": {
|
||||
"Column": "Macchina in Modo Automatico",
|
||||
"MemConf": "DB700.DBX0.2",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 2
|
||||
},
|
||||
"DB700.DBX0.3": {
|
||||
"Column": "Presenza Allarmi in Macchina da PLC",
|
||||
"MemConf": "DB700.DBX0.3",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 3
|
||||
},
|
||||
"DB700.DBX0.5": {
|
||||
"Column": "Presenza Allarmi da Programma Cicli",
|
||||
"MemConf": "DB700.DBX0.5",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 5
|
||||
},
|
||||
"DB700.DBD4": {
|
||||
"Column": "Giri Mola Giri/Min",
|
||||
"MemConf": "DB700.DBD4",
|
||||
"DataType": "DWord",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB700.DBX20.0": {
|
||||
"Column": "Inzio Ciclo di Rettifica",
|
||||
"MemConf": "DB700.DBX20.0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 0
|
||||
},
|
||||
"DB700.DBX20.1": {
|
||||
"Column": "Fine Ciclo di Rettifica",
|
||||
"MemConf": "DB700.DBX20.1",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 1
|
||||
},
|
||||
"DB800.DBB0": {
|
||||
"Column": "Numero / Nome Commessa",
|
||||
"MemConf": "DB800.DBB0",
|
||||
"DataType": "String",
|
||||
"memByteSize": 22
|
||||
},
|
||||
"DB800.DBB44": {
|
||||
"Column": "Codice disegno Pezzo",
|
||||
"MemConf": "DB800.DBB44",
|
||||
"DataType": "String",
|
||||
"memByteSize": 22
|
||||
}
|
||||
}
|
||||
},
|
||||
"parametersList": {
|
||||
"DB700.DBX0.2": {
|
||||
"Column": "Macchina in Modo Automatico",
|
||||
"MemConf": "DB700.DBX0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 2
|
||||
},
|
||||
"DB700.DBX0.3": {
|
||||
"Column": "Presenza Allarmi in Macchina da PLC",
|
||||
"MemConf": "DB700.DBX0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 3
|
||||
},
|
||||
"DB700.DBX0.5": {
|
||||
"Column": "Presenaz Allarmi da Programma Cicli",
|
||||
"MemConf": "DB700.DBX0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 5
|
||||
},
|
||||
"DB700.DBD4": {
|
||||
"Column": "Giri Mola Giri/Min",
|
||||
"MemConf": "DB700.DBD4",
|
||||
"DataType": "DWord",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB700.DBX20.0": {
|
||||
"Column": "Inzio Ciclo di Rettifica",
|
||||
"MemConf": "DB700.DBX20",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 0
|
||||
},
|
||||
"DB700.DBX20.1": {
|
||||
"Column": "Fine Ciclo di Rettifica",
|
||||
"MemConf": "DB700.DBX20",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 1
|
||||
},
|
||||
"DB800.DBB0": {
|
||||
"Column": "Numero / Nome Commessa",
|
||||
"MemConf": "DB800.DBB0",
|
||||
"DataType": "String",
|
||||
"memByteSize": 20
|
||||
},
|
||||
"DB800.DBB44": {
|
||||
"Column": "Codice disegno Pezzo",
|
||||
"MemConf": "DB800.DBB44",
|
||||
"DataType": "String",
|
||||
"memByteSize": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"confPLC": {
|
||||
"ipAdrr": "192.168.0.102",
|
||||
"tipoCpu": "S71500",
|
||||
"rack": 0,
|
||||
"slot": 1
|
||||
},
|
||||
"triggerList": {
|
||||
"DB999.DBB0": {
|
||||
"Column": "Trigger",
|
||||
"MemConf": "DB999.DBB0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"TriggerVal": "True",
|
||||
"bitAdr": 0
|
||||
}
|
||||
},
|
||||
"parametersList": {
|
||||
"DB999.DBB8": {
|
||||
"Column": "Valore 1",
|
||||
"MemConf": "DB999.DBB8",
|
||||
"DataType": "Word",
|
||||
"memByteSize": 2
|
||||
},
|
||||
"DB999.DBB10": {
|
||||
"Column": "Valore 2",
|
||||
"MemConf": "DB999.DBB10",
|
||||
"DataType": "Word",
|
||||
"memByteSize": 2
|
||||
},
|
||||
"DB999.DBB16": {
|
||||
"Column": "Valore 3",
|
||||
"MemConf": "DB999.DBB16",
|
||||
"DataType": "DWord",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB999.DBB20": {
|
||||
"Column": "Valore 4",
|
||||
"MemConf": "DB999.DBB20",
|
||||
"DataType": "DWord",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB999.DBB32": {
|
||||
"Column": "Valore 5",
|
||||
"MemConf": "DB999.DBB32",
|
||||
"DataType": "Real",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB999.DBB36": {
|
||||
"Column": "Valore 6",
|
||||
"MemConf": "DB999.DBB36",
|
||||
"DataType": "Real",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB999.DBB40": {
|
||||
"Column": "Valore 7",
|
||||
"MemConf": "DB999.DBB306",
|
||||
"DataType": "Word",
|
||||
"memByteSize": 2
|
||||
},
|
||||
"DB999.DBB48": {
|
||||
"Column": "Valore 8",
|
||||
"MemConf": "DB999.DBB48",
|
||||
"DataType": "String",
|
||||
"memByteSize": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +1,44 @@
|
||||
{
|
||||
"confPLC": {
|
||||
"ipAdrr": "192.168.0.102",
|
||||
"tipoCpu": "S71500",
|
||||
"rack": 0,
|
||||
"slot": 1
|
||||
},
|
||||
"triggerList": {
|
||||
"DB999.DBB0": {
|
||||
"Column": "Trigger",
|
||||
"MemConf": "DB999.DBB0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"TriggerVal": "True",
|
||||
"bitAdr": 0
|
||||
"confPLC": {
|
||||
"ipAdrr": "192.168.0.102",
|
||||
"tipoCpu": "S71500",
|
||||
"rack": 0,
|
||||
"slot": 1
|
||||
},
|
||||
"triggerList": {
|
||||
"DB604.DBX3.7": {
|
||||
"Column": "Trigger",
|
||||
"MemConf": "DB604.DBX3.7",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"TriggerVal": "True",
|
||||
"bitAdr": 7
|
||||
}
|
||||
},
|
||||
"parametersList": {
|
||||
"DB606.DBB0": {
|
||||
"Column": "Lotto",
|
||||
"MemConf": "DB606.DBB0",
|
||||
"DataType": "Word",
|
||||
"memByteSize": 2
|
||||
},
|
||||
"DB606.DBB2": {
|
||||
"Column": "Pezzi Fatti",
|
||||
"MemConf": "DB606.DBB2",
|
||||
"DataType": "Word",
|
||||
"memByteSize": 2
|
||||
},
|
||||
"DB604.DBB18": {
|
||||
"Column": "TC Lordo",
|
||||
"MemConf": "DB604.DBB18",
|
||||
"DataType": "DWord",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB604.DBB22": {
|
||||
"Column": "TC Netto",
|
||||
"MemConf": "DB604.DBB22",
|
||||
"DataType": "DWord",
|
||||
"memByteSize": 4
|
||||
}
|
||||
}
|
||||
},
|
||||
"parametersList": {
|
||||
"DB999.DBB8": {
|
||||
"Column": "Valore 1",
|
||||
"MemConf": "DB999.DBB8",
|
||||
"DataType": "Word",
|
||||
"memByteSize": 2
|
||||
},
|
||||
"DB999.DBB10": {
|
||||
"Column": "Valore 2",
|
||||
"MemConf": "DB999.DBB10",
|
||||
"DataType": "Word",
|
||||
"memByteSize": 2
|
||||
},
|
||||
"DB999.DBB16": {
|
||||
"Column": "Valore 3",
|
||||
"MemConf": "DB999.DBB16",
|
||||
"DataType": "DWord",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB999.DBB20": {
|
||||
"Column": "Valore 4",
|
||||
"MemConf": "DB999.DBB20",
|
||||
"DataType": "DWord",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB999.DBB32": {
|
||||
"Column": "Valore 5",
|
||||
"MemConf": "DB999.DBB32",
|
||||
"DataType": "Real",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB999.DBB36": {
|
||||
"Column": "Valore 6",
|
||||
"MemConf": "DB999.DBB36",
|
||||
"DataType": "Real",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB999.DBB40": {
|
||||
"Column": "Valore 7",
|
||||
"MemConf": "DB999.DBB306",
|
||||
"DataType": "Word",
|
||||
"memByteSize": 2
|
||||
},
|
||||
"DB999.DBB48": {
|
||||
"Column": "Valore 8",
|
||||
"MemConf": "DB999.DBB48",
|
||||
"DataType": "String",
|
||||
"memByteSize": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +1,73 @@
|
||||
{
|
||||
"confPLC": {
|
||||
"ipAdrr": "192.168.0.51",
|
||||
"tipoCpu": "S7300",
|
||||
"rack": 0,
|
||||
"slot": 2
|
||||
},
|
||||
"triggerList": {
|
||||
"DB700.DBX0.0": {
|
||||
"Column": "Trigger",
|
||||
"MemConf": "DB700.DBX0.0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"TriggerVal": "True",
|
||||
"bitAdr": 0
|
||||
"confPLC": {
|
||||
"ipAdrr": "192.168.0.52",
|
||||
"tipoCpu": "S7300",
|
||||
"rack": 0,
|
||||
"slot": 2
|
||||
},
|
||||
"triggerList": {
|
||||
"DB700.DBX0.0": {
|
||||
"Column": "Trigger",
|
||||
"MemConf": "DB700.DBX0.0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"TriggerVal": "True",
|
||||
"bitAdr": 0
|
||||
}
|
||||
},
|
||||
"parametersList": {
|
||||
"DB700.DBX0.2": {
|
||||
"Column": "Macchina in Modo Automatico",
|
||||
"MemConf": "DB700.DBX0.2",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 2
|
||||
},
|
||||
"DB700.DBX0.3": {
|
||||
"Column": "Presenza Allarmi in Macchina da PLC",
|
||||
"MemConf": "DB700.DBX0.3",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 3
|
||||
},
|
||||
"DB700.DBX0.5": {
|
||||
"Column": "Presenza Allarmi da Programma Cicli",
|
||||
"MemConf": "DB700.DBX0.5",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 5
|
||||
},
|
||||
"DB700.DBD4": {
|
||||
"Column": "Giri Mola Giri/Min",
|
||||
"MemConf": "DB700.DBD4",
|
||||
"DataType": "DWord",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB700.DBX20.0": {
|
||||
"Column": "Inzio Ciclo di Rettifica",
|
||||
"MemConf": "DB700.DBX20.0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 0
|
||||
},
|
||||
"DB700.DBX20.1": {
|
||||
"Column": "Fine Ciclo di Rettifica",
|
||||
"MemConf": "DB700.DBX20.1",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 1
|
||||
},
|
||||
"DB800.DBB0": {
|
||||
"Column": "Numero / Nome Commessa",
|
||||
"MemConf": "DB800.DBB0",
|
||||
"DataType": "String",
|
||||
"memByteSize": 22
|
||||
},
|
||||
"DB800.DBB44": {
|
||||
"Column": "Codice disegno Pezzo",
|
||||
"MemConf": "DB800.DBB44",
|
||||
"DataType": "String",
|
||||
"memByteSize": 22
|
||||
}
|
||||
}
|
||||
},
|
||||
"parametersList": {
|
||||
"DB700.DBX0.2": {
|
||||
"Column": "Macchina in Modo Automatico",
|
||||
"MemConf": "DB700.DBX0.2",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 2
|
||||
},
|
||||
"DB700.DBX0.3": {
|
||||
"Column": "Presenza Allarmi in Macchina da PLC",
|
||||
"MemConf": "DB700.DBX0.3",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 3
|
||||
},
|
||||
"DB700.DBX0.5": {
|
||||
"Column": "Presenza Allarmi da Programma Cicli",
|
||||
"MemConf": "DB700.DBX0.5",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 5
|
||||
},
|
||||
"DB700.DBD4": {
|
||||
"Column": "Giri Mola Giri/Min",
|
||||
"MemConf": "DB700.DBD4",
|
||||
"DataType": "DWord",
|
||||
"memByteSize": 4
|
||||
},
|
||||
"DB700.DBX20.0": {
|
||||
"Column": "Inzio Ciclo di Rettifica",
|
||||
"MemConf": "DB700.DBX20.0",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 0
|
||||
},
|
||||
"DB700.DBX20.1": {
|
||||
"Column": "Fine Ciclo di Rettifica",
|
||||
"MemConf": "DB700.DBX20.1",
|
||||
"DataType": "Bit",
|
||||
"memByteSize": 1,
|
||||
"bitAdr": 1
|
||||
},
|
||||
"DB800.DBB0": {
|
||||
"Column": "Numero / Nome Commessa",
|
||||
"MemConf": "DB800.DBB0",
|
||||
"DataType": "String",
|
||||
"memByteSize": 20
|
||||
},
|
||||
"DB800.DBB44": {
|
||||
"Column": "Codice disegno Pezzo",
|
||||
"MemConf": "DB800.DBB44",
|
||||
"DataType": "String",
|
||||
"memByteSize": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -303,6 +303,37 @@ namespace IOB.WIN.FileExp
|
||||
{
|
||||
lgInfo("Connection error!");
|
||||
}
|
||||
checkCreateOutFile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esecuzione task di campionamento
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void plcSampleTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
// leggo aree di memoria triggers dal PLC
|
||||
reloadTriggersFromPLC();
|
||||
|
||||
// verifico valore confrontando con i precedenti...
|
||||
if (dataChanged())
|
||||
{
|
||||
checkCreateOutFile();
|
||||
// invio su file
|
||||
saveToFile();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region helper methods
|
||||
|
||||
/// <summary>
|
||||
/// VErifica se esista file OUT altrimenti lo crea
|
||||
/// </summary>
|
||||
private void checkCreateOutFile()
|
||||
{
|
||||
// verifico esistenza file sennò creo
|
||||
if (!File.Exists(outFilePath))
|
||||
{
|
||||
@@ -326,29 +357,6 @@ namespace IOB.WIN.FileExp
|
||||
File.WriteAllText(outFilePath, fileContent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esecuzione task di campionamento
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void plcSampleTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
// leggo aree di memoria triggers dal PLC
|
||||
reloadTriggersFromPLC();
|
||||
|
||||
// verifico valore confrontando con i precedenti...
|
||||
if (dataChanged())
|
||||
{
|
||||
// invio su file
|
||||
saveToFile();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region helper methods
|
||||
|
||||
/// <summary>
|
||||
/// salva i dati sul FILE in append
|
||||
/// </summary>
|
||||
@@ -370,38 +378,45 @@ namespace IOB.WIN.FileExp
|
||||
outVal = "";
|
||||
// leggo!
|
||||
var currMem = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte);
|
||||
|
||||
// converto lettura secondo il tipo!
|
||||
switch (item.Value.DataType)
|
||||
// check dati restituiti...
|
||||
if (currMem.Length > 0)
|
||||
{
|
||||
case S7DataType.Bit:
|
||||
// uso memSize
|
||||
outVal = S7.Net.Types.Bit.FromByte(currMem[0], item.Value.bitAdr).ToString();
|
||||
break;
|
||||
case S7DataType.Byte:
|
||||
outVal = S7.Net.Types.Byte.FromByteArray(currMem.ToArray()).ToString();
|
||||
break;
|
||||
case S7DataType.Word:
|
||||
outVal = S7.Net.Types.Word.FromByteArray(currMem.ToArray()).ToString();
|
||||
break;
|
||||
case S7DataType.DWord:
|
||||
outVal = S7.Net.Types.DWord.FromByteArray(currMem.ToArray()).ToString();
|
||||
break;
|
||||
case S7DataType.Real:
|
||||
outVal = S7.Net.Types.Double.FromByteArray(currMem.ToArray()).ToString();
|
||||
break;
|
||||
case S7DataType.String:
|
||||
// prendo 2° valore (num max valori)
|
||||
int numChar = currMem[1];
|
||||
// poi prendo la stringa...
|
||||
for (int i = 2; i < numChar + 2; i++)
|
||||
{
|
||||
outVal += Char.ConvertFromUtf32(currMem[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
outVal = BitConverter.ToString(currMem);
|
||||
break;
|
||||
// converto lettura secondo il tipo!
|
||||
switch (item.Value.DataType)
|
||||
{
|
||||
case S7DataType.Bit:
|
||||
// uso memSize
|
||||
outVal = S7.Net.Types.Bit.FromByte(currMem[0], item.Value.bitAdr).ToString();
|
||||
break;
|
||||
case S7DataType.Byte:
|
||||
outVal = S7.Net.Types.Byte.FromByteArray(currMem.ToArray()).ToString();
|
||||
break;
|
||||
case S7DataType.Word:
|
||||
outVal = S7.Net.Types.Word.FromByteArray(currMem.ToArray()).ToString();
|
||||
break;
|
||||
case S7DataType.DWord:
|
||||
outVal = S7.Net.Types.DWord.FromByteArray(currMem.ToArray()).ToString();
|
||||
break;
|
||||
case S7DataType.Real:
|
||||
outVal = S7.Net.Types.Double.FromByteArray(currMem.ToArray()).ToString();
|
||||
break;
|
||||
case S7DataType.String:
|
||||
// prendo 2° valore (num max valori)
|
||||
int numChar = currMem[1];
|
||||
// poi prendo la stringa...
|
||||
for (int i = 2; i < numChar + 2; i++)
|
||||
{
|
||||
outVal += Char.ConvertFromUtf32(currMem[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
outVal = BitConverter.ToString(currMem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"Errore: ricevuto 0 byte per DB{memoria.DbNum}.{memoria.indiceMem:000}");
|
||||
}
|
||||
newData.Add(outVal);
|
||||
}
|
||||
|
||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
||||
// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build
|
||||
// usando l'asterisco '*' come illustrato di seguito:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.2.2007.34")]
|
||||
[assembly: AssemblyFileVersion("1.2.2007.34")]
|
||||
[assembly: AssemblyVersion("1.2.2007.37")]
|
||||
[assembly: AssemblyFileVersion("1.2.2007.37")]
|
||||
|
||||
Reference in New Issue
Block a user