fix lettura nuovo formato variabili BYTE (BOOL al posto di BIT...)
This commit is contained in:
@@ -31,10 +31,6 @@ namespace MTC_Adapter
|
||||
/// Configurazione valori da leggere IOT_String
|
||||
/// </summary>
|
||||
public otherData[] mapIOT_String;
|
||||
/// <summary>
|
||||
/// variabile globale x usare IOT MEMORY (!!! da eliminare alla fine dei test)
|
||||
/// </summary>
|
||||
protected bool useIotMem = true;
|
||||
|
||||
/// <summary>
|
||||
/// Carico file conf dati IOT
|
||||
@@ -111,7 +107,11 @@ namespace MTC_Adapter
|
||||
if (linea.Substring(0, 1) != "#")
|
||||
{
|
||||
// se finisce per BIT allora processo bit-a-bit...
|
||||
if (linea.EndsWith("BIT"))
|
||||
if (linea.EndsWith("BYTE"))
|
||||
{
|
||||
vettoreConf[numRiga] = decodeOtherData(linea, utils.CRC("testCharSep"), "", 1, memSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -134,11 +134,6 @@ namespace MTC_Adapter
|
||||
}
|
||||
vettoreConf[numRiga] = decodeBitData(linea, utils.CRC("testCharSep"), "", byteNum, 1, bitNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
//int.TryParse(linea.Split(utils.CRC("testCharSep"))[0], out byteNum);
|
||||
vettoreConf[numRiga] = decodeOtherData(linea, utils.CRC("testCharSep"), "", 1, memSize);
|
||||
}
|
||||
numRiga++;
|
||||
}
|
||||
}
|
||||
@@ -626,120 +621,112 @@ namespace MTC_Adapter
|
||||
{
|
||||
base.getGlobalData();
|
||||
|
||||
// 2017.03.07 IN BLOCCO processo TUTTI i valori della memoria WORD/DWORD...
|
||||
if (useIotMem)
|
||||
// accodo dati path in DataMonitor......
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (connectionOk)
|
||||
{
|
||||
processAllMemory();
|
||||
// leggo TUTTO il blocco di memoria
|
||||
inizio = DateTime.Now;
|
||||
ncDevice.ReadBuffer();
|
||||
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R-PLC_FullMemoryRead", ncDevice.PLC_MemoryRead.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||||
}
|
||||
else
|
||||
{
|
||||
// accodo dati path in DataMonitor......
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (connectionOk)
|
||||
{
|
||||
// leggo TUTTO il blocco di memoria
|
||||
inizio = DateTime.Now;
|
||||
ncDevice.ReadBuffer();
|
||||
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R-PLC_FullMemoryRead", ncDevice.PLC_MemoryRead.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||||
}
|
||||
else
|
||||
{
|
||||
lg.Error("Errore connessione mancante in getGlobalData");
|
||||
}
|
||||
|
||||
// dati override feed/speed...
|
||||
Byte v82 = ncDevice.PLC_MemoryAreaV[14];
|
||||
Byte v83 = ncDevice.PLC_MemoryAreaV[15];
|
||||
// 2 byte x speed da copiare...
|
||||
byte[] tmpByte = new byte[2];
|
||||
Buffer.BlockCopy(ncDevice.PLC_MemoryAreaV, 16, tmpByte, 0, 2);
|
||||
short v84 = BitConverter.ToInt16(tmpByte, 0);
|
||||
// lista allarmi PLC/CNC
|
||||
Byte v87 = ncDevice.PLC_MemoryAreaV[19]; // Allarme CN (almeno 1?!?)
|
||||
|
||||
// -------------------------------------------
|
||||
// recupero dati Feed/Speed/override
|
||||
// FeedOver: 100% = 213 (il pannello è 0-120 --> 0-255, quindi 100% è 100/120*255=213)
|
||||
FeedRateOver = Convert.ToInt16((decimal)(v82 * 100) / 213);
|
||||
sb.AppendLine(string.Format("FeedRateOver: {0} %", FeedRateOver));
|
||||
// SpeedOver: 50% = 128
|
||||
SpeedRateOver = Convert.ToInt16((decimal)(v83 * 100) / 255);
|
||||
sb.AppendLine(string.Format("SpeedRateOver: {0} %", SpeedRateOver));
|
||||
// Speed S5000 OK!!!
|
||||
SpeedRate = v84;
|
||||
sb.AppendLine(string.Format("SpeedRate: {0} rpm", SpeedRate));
|
||||
// -------------------------------------------
|
||||
|
||||
// da recuperare da qualche parte?!?
|
||||
UnOpLoad = 0;
|
||||
sb.AppendLine(string.Format("Load: {0}", UnOpLoad));
|
||||
|
||||
// -------------------------------------------
|
||||
// recupero dati dai contatori EOK
|
||||
bool needSave = false;
|
||||
|
||||
// ore totali accensione
|
||||
int MinMaccOn = (int)ncDevice.PLC_MemoryAreaEOK[0];
|
||||
int OreMaccOn = (int)ncDevice.PLC_MemoryAreaEOK[1];
|
||||
istOreMaccOn = OreMaccOn + (double)MinMaccOn / 60;
|
||||
needSave = procOreMaccOn(needSave);
|
||||
|
||||
// ore totali lavoro
|
||||
int MinMaccLav = (int)ncDevice.PLC_MemoryAreaEOK[2];
|
||||
int OreMaccLav = (int)ncDevice.PLC_MemoryAreaEOK[3];
|
||||
istOreMaccLav = OreMaccLav + (double)MinMaccLav / 60;
|
||||
needSave = procOreMaccLav(needSave);
|
||||
|
||||
// giri totali degli elettromandrini!
|
||||
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
||||
{
|
||||
istGiriElettrom[i] = (uint)ncDevice.PLC_MemoryAreaEOK[4 + i];
|
||||
}
|
||||
needSave = procGiriTotUnOp(needSave);
|
||||
needSave = procNumCU(needSave);
|
||||
|
||||
// per ESA calcolo a mano se ci sia stato impiego assi... salvo le istantanee mov precedenti...
|
||||
double precVal = 0;
|
||||
DateTime adesso = DateTime.Now;
|
||||
TimeSpan accumTime = adesso.Subtract(lastChekAccumTimeAxis);
|
||||
|
||||
// spostamento totale assi!
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
precVal = istDistMovAssi[i];
|
||||
// primo è metri, secondo km (moltiplico x 1000)
|
||||
istDistMovAssi[i] = ncDevice.PLC_MemoryAreaEOK[8 + 2 * i] + ncDevice.PLC_MemoryAreaEOK[9 + 2 * i] * 1000;
|
||||
// verifico SE devo aggiungere tempo lavoro sui singoli assi (se si sono spostati...) -- è a maglie LARGHE poiché leggiamo lo "scatto ogni metro" x cui se campiono velocemente ma assi muovono lenti prendo MENO tempo di movimento del reale...
|
||||
if (precVal != istDistMovAssi[i])
|
||||
{
|
||||
istAccTimeAssi[i] += accumTime.TotalHours;
|
||||
}
|
||||
}
|
||||
// salvo valore lastChekAccumTimeAxis
|
||||
lastChekAccumTimeAxis = adesso;
|
||||
|
||||
needSave = procMovTotAssi(needSave);
|
||||
needSave = procAccTimeAssi(needSave);
|
||||
needSave = procProgrName(needSave);
|
||||
needSave = procPartId(needSave);
|
||||
needSave = procPzProd(needSave);
|
||||
needSave = procNumInvAssi(needSave);
|
||||
needSave = procVacPump(needSave);
|
||||
needSave = procVacAct(needSave);
|
||||
needSave = procLubro(needSave);
|
||||
|
||||
|
||||
|
||||
// salvo se necessario!
|
||||
if (needSave) parentForm.persistData();
|
||||
// -------------------------------------------
|
||||
|
||||
|
||||
// copio allarmi in vettore generale AlarFlags (dove lo gestisce)...
|
||||
Buffer.BlockCopy(ncDevice.PLC_MemoryAreaAllarmi, 0, AlarmFlags, 0, ncDevice.PLC_MemoryAreaAllarmi.Length);
|
||||
parentForm.dataMonitor = sb.ToString();
|
||||
lg.Error("Errore connessione mancante in getGlobalData");
|
||||
}
|
||||
|
||||
// dati override feed/speed...
|
||||
Byte v82 = ncDevice.PLC_MemoryAreaV[14];
|
||||
Byte v83 = ncDevice.PLC_MemoryAreaV[15];
|
||||
// 2 byte x speed da copiare...
|
||||
byte[] tmpByte = new byte[2];
|
||||
Buffer.BlockCopy(ncDevice.PLC_MemoryAreaV, 16, tmpByte, 0, 2);
|
||||
short v84 = BitConverter.ToInt16(tmpByte, 0);
|
||||
// lista allarmi PLC/CNC
|
||||
Byte v87 = ncDevice.PLC_MemoryAreaV[19]; // Allarme CN (almeno 1?!?)
|
||||
|
||||
// -------------------------------------------
|
||||
// recupero dati Feed/Speed/override
|
||||
// FeedOver: 100% = 213 (il pannello è 0-120 --> 0-255, quindi 100% è 100/120*255=213)
|
||||
FeedRateOver = Convert.ToInt16((decimal)(v82 * 100) / 213);
|
||||
sb.AppendLine(string.Format("FeedRateOver: {0} %", FeedRateOver));
|
||||
// SpeedOver: 50% = 128
|
||||
SpeedRateOver = Convert.ToInt16((decimal)(v83 * 100) / 255);
|
||||
sb.AppendLine(string.Format("SpeedRateOver: {0} %", SpeedRateOver));
|
||||
// Speed S5000 OK!!!
|
||||
SpeedRate = v84;
|
||||
sb.AppendLine(string.Format("SpeedRate: {0} rpm", SpeedRate));
|
||||
// -------------------------------------------
|
||||
|
||||
// da recuperare da qualche parte?!?
|
||||
UnOpLoad = 0;
|
||||
sb.AppendLine(string.Format("Load: {0}", UnOpLoad));
|
||||
|
||||
// -------------------------------------------
|
||||
// recupero dati dai contatori EOK
|
||||
bool needSave = false;
|
||||
|
||||
// ore totali accensione
|
||||
int MinMaccOn = (int)ncDevice.PLC_MemoryAreaEOK[0];
|
||||
int OreMaccOn = (int)ncDevice.PLC_MemoryAreaEOK[1];
|
||||
istOreMaccOn = OreMaccOn + (double)MinMaccOn / 60;
|
||||
needSave = procOreMaccOn(needSave);
|
||||
|
||||
// ore totali lavoro
|
||||
int MinMaccLav = (int)ncDevice.PLC_MemoryAreaEOK[2];
|
||||
int OreMaccLav = (int)ncDevice.PLC_MemoryAreaEOK[3];
|
||||
istOreMaccLav = OreMaccLav + (double)MinMaccLav / 60;
|
||||
needSave = procOreMaccLav(needSave);
|
||||
|
||||
// giri totali degli elettromandrini!
|
||||
for (int i = 0; i < currAdpConf.nUnOp; i++)
|
||||
{
|
||||
istGiriElettrom[i] = (uint)ncDevice.PLC_MemoryAreaEOK[4 + i];
|
||||
}
|
||||
needSave = procGiriTotUnOp(needSave);
|
||||
needSave = procNumCU(needSave);
|
||||
|
||||
// per ESA calcolo a mano se ci sia stato impiego assi... salvo le istantanee mov precedenti...
|
||||
double precVal = 0;
|
||||
DateTime adesso = DateTime.Now;
|
||||
TimeSpan accumTime = adesso.Subtract(lastChekAccumTimeAxis);
|
||||
|
||||
// spostamento totale assi!
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
precVal = istDistMovAssi[i];
|
||||
// primo è metri, secondo km (moltiplico x 1000)
|
||||
istDistMovAssi[i] = ncDevice.PLC_MemoryAreaEOK[8 + 2 * i] + ncDevice.PLC_MemoryAreaEOK[9 + 2 * i] * 1000;
|
||||
// verifico SE devo aggiungere tempo lavoro sui singoli assi (se si sono spostati...) -- è a maglie LARGHE poiché leggiamo lo "scatto ogni metro" x cui se campiono velocemente ma assi muovono lenti prendo MENO tempo di movimento del reale...
|
||||
if (precVal != istDistMovAssi[i])
|
||||
{
|
||||
istAccTimeAssi[i] += accumTime.TotalHours;
|
||||
}
|
||||
}
|
||||
// salvo valore lastChekAccumTimeAxis
|
||||
lastChekAccumTimeAxis = adesso;
|
||||
|
||||
needSave = procMovTotAssi(needSave);
|
||||
needSave = procAccTimeAssi(needSave);
|
||||
needSave = procProgrName(needSave);
|
||||
needSave = procPartId(needSave);
|
||||
needSave = procPzProd(needSave);
|
||||
needSave = procNumInvAssi(needSave);
|
||||
needSave = procVacPump(needSave);
|
||||
needSave = procVacAct(needSave);
|
||||
needSave = procLubro(needSave);
|
||||
|
||||
|
||||
|
||||
// salvo se necessario!
|
||||
if (needSave) parentForm.persistData();
|
||||
// -------------------------------------------
|
||||
|
||||
|
||||
// copio allarmi in vettore generale AlarFlags (dove lo gestisce)...
|
||||
Buffer.BlockCopy(ncDevice.PLC_MemoryAreaAllarmi, 0, AlarmFlags, 0, ncDevice.PLC_MemoryAreaAllarmi.Length);
|
||||
parentForm.dataMonitor = sb.ToString();
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Path percorso file prod
|
||||
@@ -891,7 +878,6 @@ namespace MTC_Adapter
|
||||
/// </summary>
|
||||
public override void processAllMemory()
|
||||
{
|
||||
//!!!FARE!!! completare e validare parti commentate...
|
||||
// inizializzo data monitor su FORM
|
||||
parentForm.dataMonitor = "";
|
||||
|
||||
@@ -923,98 +909,89 @@ namespace MTC_Adapter
|
||||
// accodo dati path in DataMonitor......
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// 2017.03.07 IN BLOCCO processo TUTTI i valori della memoria BYTE...
|
||||
if (useIotMem)
|
||||
// verifica macchina accesa...
|
||||
Byte V73 = ncDevice.PLC_MemoryAreaV[5];
|
||||
|
||||
if (((StFlag8)V73).HasFlag(StFlag8.B2))
|
||||
{
|
||||
processAllMemory();
|
||||
mPower.Value = "ON";
|
||||
}
|
||||
else
|
||||
{
|
||||
// verifica macchina accesa...
|
||||
Byte V73 = ncDevice.PLC_MemoryAreaV[5];
|
||||
|
||||
if (((StFlag8)V73).HasFlag(StFlag8.B2))
|
||||
{
|
||||
mPower.Value = "ON";
|
||||
}
|
||||
else
|
||||
{
|
||||
mPower.Value = "OFF";
|
||||
}
|
||||
|
||||
// switch su EXE mode...
|
||||
/*
|
||||
* MODO_X V[70/71] --> byte (2-3)
|
||||
* V70.2 = Modo RUN
|
||||
* V70.3 = Modo FeedHold
|
||||
* V71.5 = Ready
|
||||
* */
|
||||
Byte V70 = ncDevice.PLC_MemoryAreaV[2];
|
||||
Byte V71 = ncDevice.PLC_MemoryAreaV[3];
|
||||
|
||||
if (((StFlag8)V70).HasFlag(StFlag8.B3))
|
||||
{
|
||||
vettPath[idxPath].mPathExeMode.Value = "FEED_HOLD"; //"FEEDHOLD";
|
||||
}
|
||||
else if (((StFlag8)V70).HasFlag(StFlag8.B2))
|
||||
{
|
||||
vettPath[idxPath].mPathExeMode.Value = "ACTIVE";
|
||||
}
|
||||
else if (((StFlag8)V71).HasFlag(StFlag8.B5))
|
||||
{
|
||||
vettPath[idxPath].mPathExeMode.Value = "READY";
|
||||
}
|
||||
//// appunto: modi da creare
|
||||
//STOPPED/HOLD(da creare)
|
||||
//INTERRUPTED(da creare)
|
||||
//OPTIONAL_STOP(da creare)
|
||||
//PROGRAM_STOPPED(da creare)
|
||||
//PROGRAM_COMPLETED(da creare)
|
||||
|
||||
|
||||
// switch su run mode...
|
||||
/*
|
||||
* MODO_X V[74].W --> byte (6)
|
||||
* 0 = Modo NESSUNO
|
||||
* 1 = Modo MANUALE
|
||||
* 2 = Modo AUTOMATICO
|
||||
* 3 = Modo POM
|
||||
* 4 = Modo MDI
|
||||
* 5 = Modo SEMIAUTOMATICO
|
||||
* 6 = Modo RAP
|
||||
* 7 = Modo TES
|
||||
* */
|
||||
uint V74 = ncDevice.PLC_MemoryAreaV[6];
|
||||
switch (V74)
|
||||
{
|
||||
case 1:
|
||||
vettPath[idxPath].mPathRunMode.Value = "EDIT";
|
||||
break;
|
||||
case 2:
|
||||
vettPath[idxPath].mPathRunMode.Value = "AUTOMATIC";
|
||||
break;
|
||||
case 3:
|
||||
vettPath[idxPath].mPathRunMode.Value = "MANUAL";
|
||||
break;
|
||||
case 4:
|
||||
vettPath[idxPath].mPathRunMode.Value = "MANUAL_DATA_INPUT";
|
||||
break;
|
||||
case 5:
|
||||
vettPath[idxPath].mPathRunMode.Value = "SEMI_AUTOMATIC"; //"SEMIAUTO";
|
||||
break;
|
||||
case 6:
|
||||
vettPath[idxPath].mPathRunMode.Value = "MANUAL"; //"RAP";
|
||||
break;
|
||||
case 7:
|
||||
vettPath[idxPath].mPathRunMode.Value = "MANUAL"; //"TES";
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
vettPath[idxPath].mPathRunMode.Value = "NA";
|
||||
break;
|
||||
}
|
||||
mPower.Value = "OFF";
|
||||
}
|
||||
|
||||
// switch su EXE mode...
|
||||
/*
|
||||
* MODO_X V[70/71] --> byte (2-3)
|
||||
* V70.2 = Modo RUN
|
||||
* V70.3 = Modo FeedHold
|
||||
* V71.5 = Ready
|
||||
* */
|
||||
Byte V70 = ncDevice.PLC_MemoryAreaV[2];
|
||||
Byte V71 = ncDevice.PLC_MemoryAreaV[3];
|
||||
|
||||
if (((StFlag8)V70).HasFlag(StFlag8.B3))
|
||||
{
|
||||
vettPath[idxPath].mPathExeMode.Value = "FEED_HOLD"; //"FEEDHOLD";
|
||||
}
|
||||
else if (((StFlag8)V70).HasFlag(StFlag8.B2))
|
||||
{
|
||||
vettPath[idxPath].mPathExeMode.Value = "ACTIVE";
|
||||
}
|
||||
else if (((StFlag8)V71).HasFlag(StFlag8.B5))
|
||||
{
|
||||
vettPath[idxPath].mPathExeMode.Value = "READY";
|
||||
}
|
||||
//// appunto: modi da creare
|
||||
//STOPPED/HOLD(da creare)
|
||||
//INTERRUPTED(da creare)
|
||||
//OPTIONAL_STOP(da creare)
|
||||
//PROGRAM_STOPPED(da creare)
|
||||
//PROGRAM_COMPLETED(da creare)
|
||||
|
||||
|
||||
// switch su run mode...
|
||||
/*
|
||||
* MODO_X V[74].W --> byte (6)
|
||||
* 0 = Modo NESSUNO
|
||||
* 1 = Modo MANUALE
|
||||
* 2 = Modo AUTOMATICO
|
||||
* 3 = Modo POM
|
||||
* 4 = Modo MDI
|
||||
* 5 = Modo SEMIAUTOMATICO
|
||||
* 6 = Modo RAP
|
||||
* 7 = Modo TES
|
||||
* */
|
||||
uint V74 = ncDevice.PLC_MemoryAreaV[6];
|
||||
switch (V74)
|
||||
{
|
||||
case 1:
|
||||
vettPath[idxPath].mPathRunMode.Value = "EDIT";
|
||||
break;
|
||||
case 2:
|
||||
vettPath[idxPath].mPathRunMode.Value = "AUTOMATIC";
|
||||
break;
|
||||
case 3:
|
||||
vettPath[idxPath].mPathRunMode.Value = "MANUAL";
|
||||
break;
|
||||
case 4:
|
||||
vettPath[idxPath].mPathRunMode.Value = "MANUAL_DATA_INPUT";
|
||||
break;
|
||||
case 5:
|
||||
vettPath[idxPath].mPathRunMode.Value = "SEMI_AUTOMATIC"; //"SEMIAUTO";
|
||||
break;
|
||||
case 6:
|
||||
vettPath[idxPath].mPathRunMode.Value = "MANUAL"; //"RAP";
|
||||
break;
|
||||
case 7:
|
||||
vettPath[idxPath].mPathRunMode.Value = "MANUAL"; //"TES";
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
vettPath[idxPath].mPathRunMode.Value = "NA";
|
||||
break;
|
||||
}
|
||||
//parentForm.dataMonitor = sb.ToString();
|
||||
}
|
||||
/// <summary>
|
||||
/// Recupera la speed override x i mandrini (UnOp)
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
# Commenti con cancelletto, struttura un variabile per riga, tipo chiave|valore (occhio che il separatore è configurato da .cofig come "testCharSep"); spazi e tabulazioni dovrei trimmarli in acquisizione (qui inseriti per comodità di lettura)
|
||||
000.0|IOT_EXEC |BIT
|
||||
001.0|IOT_HOLD |BIT
|
||||
002.0|IOT_EMG |BIT
|
||||
003.0|IOT_ALRM |BIT
|
||||
004|IOT_OVRF |BYTE
|
||||
005|IOT_OVRS |BYTE
|
||||
006|IOT_LUB_01_STA |BYTE
|
||||
007|IOT_LUB_01_CNT |BYTE
|
||||
008|IOT_I_MD_01 |BYTE
|
||||
009|IOT_I_MD_02 |BYTE
|
||||
010|IOT_I_MD_03 |BYTE
|
||||
011|IOT_I_MD_04 |BYTE
|
||||
012|IOT_I_MD_05 |BYTE
|
||||
013|IOT_I_MD_06 |BYTE
|
||||
014|IOT_I_MD_07 |BYTE
|
||||
015|IOT_I_MD_08 |BYTE
|
||||
016|IOT_PGMR_A1 |BYTE
|
||||
017|IOT_PGMR_A2 |BYTE
|
||||
018|IOT_PGMR_A3 |BYTE
|
||||
019|IOT_PGMR_A4 |BYTE
|
||||
0.0|IOT_EXEC |BOOL
|
||||
0.1|IOT_HOLD |BOOL
|
||||
0.2|IOT_EMG |BOOL
|
||||
0.3|IOT_ALRM |BOOL
|
||||
0.4|IOT_MACHON |BOOL
|
||||
0.5|IOT_READY |BOOL
|
||||
0.6|libero |BOOL
|
||||
0.7|libero |BOOL
|
||||
001|libero |BYTE
|
||||
002|libero |BYTE
|
||||
003|IOT_MODECN |BYTE
|
||||
004|IOT_OVRF |BYTE
|
||||
005|IOT_OVRS |BYTE
|
||||
006|IOT_LUB_01_STA |BYTE
|
||||
007|IOT_LUB_01_CNT |BYTE
|
||||
008|IOT_I_MD_01 |BYTE
|
||||
009|IOT_I_MD_02 |BYTE
|
||||
010|IOT_I_MD_03 |BYTE
|
||||
011|IOT_I_MD_04 |BYTE
|
||||
012|IOT_I_MD_05 |BYTE
|
||||
013|IOT_I_MD_06 |BYTE
|
||||
014|IOT_I_MD_07 |BYTE
|
||||
015|IOT_I_MD_08 |BYTE
|
||||
Reference in New Issue
Block a user