788 lines
30 KiB
C#
788 lines
30 KiB
C#
using IOB_UT;
|
|
using MapoSDK;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace IOB_WIN
|
|
{
|
|
public class IobSimula : IobGeneric
|
|
{
|
|
#region Protected Fields
|
|
|
|
/// <summary>
|
|
/// Parametri simulazione oscillazione bit 2
|
|
/// </summary>
|
|
protected simPar bit2;
|
|
|
|
/// <summary>
|
|
/// Parametri simulazione oscillazione bit 3
|
|
/// </summary>
|
|
protected simPar bit3;
|
|
|
|
/// <summary>
|
|
/// Parametri simulazione oscillazione bit 4
|
|
/// </summary>
|
|
protected simPar bit4;
|
|
|
|
/// <summary>
|
|
/// Parametri simulazione oscillazione bit 5
|
|
/// </summary>
|
|
protected simPar bit5;
|
|
|
|
/// <summary>
|
|
/// Parametri simulazione oscillazione bit 6
|
|
/// </summary>
|
|
protected simPar bit6;
|
|
|
|
/// <summary>
|
|
/// Parametri simulazione oscillazione bit 7
|
|
/// </summary>
|
|
protected simPar bit7;
|
|
|
|
/// <summary>
|
|
/// pallet corrente
|
|
/// </summary>
|
|
protected int cP = 1;
|
|
|
|
/// <summary>
|
|
/// ultimo controllo decremento eventi
|
|
/// </summary>
|
|
protected DateTime lastEvCheck;
|
|
|
|
/// <summary>
|
|
/// Ultimo istante in cui sono stati generati dati di simulazione
|
|
/// </summary>
|
|
protected DateTime lastSimData;
|
|
|
|
/// <summary>
|
|
/// Durata minima ODL x reset quando pezzi iob > pezzi macchina...
|
|
/// </summary>
|
|
protected int minDurataODL = 480;
|
|
|
|
/// <summary>
|
|
/// pallet successivo (next)
|
|
/// </summary>
|
|
protected int nP = 1;
|
|
|
|
/// <summary>
|
|
/// periodo base del simulatore (in millisecondi)
|
|
/// </summary>
|
|
protected int periodoMSec = 1000;
|
|
|
|
/// <summary>
|
|
/// variabile di appoggio x stato segnale contapezzo
|
|
/// </summary>
|
|
protected bool sigPzCount = false;
|
|
|
|
/// <summary>
|
|
/// BOOL: indica se simulare powerOn/Off (bit 0 e 1) compresi WarmUp e CoolDown
|
|
/// </summary>
|
|
protected bool simPowerOnOff;
|
|
|
|
/// <summary>
|
|
/// Tempo di MINIMO attesa x simulazione parametri
|
|
/// </summary>
|
|
protected int waitSimPar = utils.CRI("waitSimPar");
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Public Fields
|
|
|
|
/// <summary>
|
|
/// Ora spegniemnto (standard)
|
|
/// </summary>
|
|
public int tOff = 22;
|
|
|
|
/// <summary>
|
|
/// Ora dia ccensione (standard)
|
|
/// </summary>
|
|
public int tOn = 6;
|
|
|
|
#endregion Public Fields
|
|
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// estende l'init della classe base...
|
|
/// </summary>
|
|
/// <param name="caller"></param>
|
|
/// <param name="adpConf"></param>
|
|
public IobSimula(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
|
{
|
|
// gestione invio ritardato contapezzi
|
|
|
|
DateTime adesso = DateTime.Now;
|
|
lastPzCountSend = adesso;
|
|
lastWarnODL = adesso;
|
|
lastEvCheck = adesso;
|
|
lastSimData = adesso;
|
|
// sistemo parametri x simulazione...
|
|
if (cIobConf.optPar.Count > 0)
|
|
{
|
|
if (!string.IsNullOrEmpty(getOptPar("PER_BASE")))
|
|
{
|
|
int.TryParse(getOptPar("PER_BASE"), out periodoMSec);
|
|
// aggiungo NOISE... +/- 20%
|
|
Random rnd = new Random();
|
|
int noise = rnd.Next(1, periodoMSec / 5);
|
|
periodoMSec += noise - (periodoMSec / 10);
|
|
}
|
|
simPowerOnOff = false;
|
|
bool.TryParse(getOptPar("SIM_POW_ON_OFF"), out simPowerOnOff);
|
|
int.TryParse(getOptPar("T_ON"), out tOn);
|
|
int.TryParse(getOptPar("T_OFF"), out tOff);
|
|
bit2 = setupSimPar("SIM_PZCNT");
|
|
bit3 = setupSimPar("SIM_ALARM");
|
|
bit4 = setupSimPar("SIM_MANU");
|
|
bit5 = setupSimPar("SIM_SLOW");
|
|
bit6 = setupSimPar("SIM_WUCD");
|
|
bit7 = setupSimPar("SIM_EMRG");
|
|
int.TryParse(getOptPar("MIN_DURATA_ODL"), out minDurataODL);
|
|
}
|
|
setParamPlc();
|
|
// ricarico da server i dati dei pezzi fatti...
|
|
lgInfo("Init contapezzi SIMULA: pzCntReload(true)");
|
|
if (!isMulti)
|
|
{
|
|
pzCntReload(true);
|
|
}
|
|
// imposto pezzi CNC ai pezzi contati da server...
|
|
contapezziPLC = contapezziIOB;
|
|
lgInfo($"Impostazione iniziale contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB}");
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Decodifica il resto dell'area x i dati accessori (allarmi, ...)
|
|
/// </summary>
|
|
private void decodeOtherData()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
|
|
/// </summary>
|
|
private void decodeToBaseBitmap()
|
|
{
|
|
// init a zero...
|
|
B_input = 0;
|
|
bool sendContapezzi = false;
|
|
/* -----------------------------------------------------
|
|
* bitmap MAPO
|
|
* B0: POWER_ON
|
|
* B1: RUN
|
|
* B2: pzCount
|
|
* B3: allarme
|
|
* B4: manuale
|
|
* B5: allarme TCiclo (SLOW)
|
|
* B6: WarmUp_CoolDown
|
|
* B7: EmergArmed (1 = NON emergenza, 0 = emergenza)
|
|
* B8: pallet 1 (SE doppio pallet)
|
|
* B9: pallet 2 (SE doppio pallet)
|
|
----------------------------------------------------- */
|
|
|
|
// di base macchina in RUN
|
|
B_input = 3;
|
|
|
|
/*----------------------------------------
|
|
* Simulazione segnali con priorità:
|
|
* - Power ON / OFF (bit0/1)
|
|
* - ALLARMI
|
|
* - MANUALE
|
|
* - SLOW
|
|
* - contapezzi
|
|
* - emergenza
|
|
*
|
|
*----------------------------------------*/
|
|
|
|
// se simulo PowerOn/Off --> spegnimento con CoolDown e accensione con WarmUp..
|
|
if (simPowerOnOff)
|
|
{
|
|
DateTime adesso = DateTime.Now;
|
|
// se l'orario è dopo le tOff (tipicamente 22) --> NO RUN...
|
|
if (adesso.Hour >= tOff || adesso.Hour <= tOn)
|
|
{
|
|
// se prima/ultima mezz'ora è ancora accesa NON in run...
|
|
if (adesso.AddMinutes(-30).Hour < tOff || adesso.AddMinutes(30).Hour > tOn)
|
|
{
|
|
B_input = 1;
|
|
}
|
|
else
|
|
{
|
|
B_input = 0;
|
|
}
|
|
// aggiungo NON emergenza...
|
|
B_input += (1 << 7);
|
|
}
|
|
}
|
|
// in primis verifico SE posso inviare in blocco i pezzi...... SE MP online e SE NON E' MULTI
|
|
if (MPOnline && !isMulti)
|
|
{
|
|
// SE IOB online...
|
|
if (IobOnline)
|
|
{
|
|
// se il contapezzi è OLTRE il valore inviato....
|
|
if (contapezziPLC > contapezziIOB)
|
|
{
|
|
// invio SOLO SE sono OLTRE i numSim pz e li invio TUTTI in blocco
|
|
if ((contapezziPLC - contapezziIOB) > minSendPzCountBlock)
|
|
{
|
|
trySendPzCountBlock();
|
|
sigPzCount = false;
|
|
}
|
|
// altrimenti invio 1 segnale
|
|
else
|
|
{
|
|
// se NON STAVA inviando di già...
|
|
if (!sigPzCount)
|
|
{
|
|
// segnalo BIT (1 pz)
|
|
B_input += (1 << 2);
|
|
sigPzCount = true;
|
|
// salvo nuovo contapezzi (incremento di 1...) + richiesta refresh conteggio
|
|
contapezziIOB++;
|
|
needRefreshPzCount = true;
|
|
// invio conferma contapezzi..
|
|
string retVal = utils.callUrl($"{urlSetPzCount}{contapezziIOB}");
|
|
// verifica salvataggio
|
|
if (retVal != contapezziIOB.ToString())
|
|
{
|
|
// errore salvataggio contapezzi
|
|
lgInfo($"Errore salvataggio Contapezzi SIMULA 01: contapezziIOB {contapezziIOB} | risposta: {retVal}");
|
|
// rileggo il counter pezzi da server
|
|
pzCntReload(true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string retVal = utils.callUrl($"{urlSetPzCount}{contapezziIOB}");
|
|
if (retVal != contapezziIOB.ToString())
|
|
{
|
|
// errore salvataggio contapezzi
|
|
lgInfo($"Errore salvataggio Contapezzi SIMULA 02: contapezziIOB {contapezziIOB} | risposta: {retVal}");
|
|
// rileggo il counter pezzi da server
|
|
pzCntReload(true);
|
|
}
|
|
sigPzCount = false;
|
|
}
|
|
}
|
|
lgInfo($"S01: Valori contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB} | contapezziPLC > contapezziIOB");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// imposto currODL a vuoto!
|
|
currODL = "";
|
|
if (periodicLog)
|
|
{
|
|
lgInfo($"SIMULA | Lettura ODL non effettuata: IobOnline: {IobOnline} | currODL impostato a vuoto");
|
|
}
|
|
}
|
|
}
|
|
|
|
// questa parte la processo SOLO SE sono in run --> B_input == 3
|
|
if (B_input == 3)
|
|
{
|
|
// di base NON emergenza
|
|
B_input += (1 << 7);
|
|
// ora controllo il resto...
|
|
if (bit3.wait <= 0)
|
|
{
|
|
// segnalo BIT
|
|
B_input += (1 << 3);
|
|
// decremento duration
|
|
bit3.duration--;
|
|
// controllo se sia scaduta la duration... in quel caso reset...
|
|
if (bit3.duration <= 0)
|
|
{
|
|
bit3 = setupSimPar("SIM_ALARM");
|
|
}
|
|
}
|
|
else if (bit6.wait <= 0)
|
|
{
|
|
// segnalo BIT
|
|
B_input += (1 << 6);
|
|
// decremento duration
|
|
bit6.duration--;
|
|
// controllo se sia scaduta la duration... in quel caso reset...
|
|
if (bit6.duration <= 0)
|
|
{
|
|
bit6 = setupSimPar("SIM_WUCD");
|
|
}
|
|
// in warm up: provo split ODL
|
|
trySplitOdl();
|
|
}
|
|
else if (bit7.wait <= 0)
|
|
{
|
|
// segnalo BIT NEGATO (emergenza)
|
|
B_input -= (1 << 7);
|
|
// decremento duration
|
|
bit7.duration--;
|
|
// controllo se sia scaduta la duration... in quel caso reset...
|
|
if (bit7.duration <= 0)
|
|
{
|
|
bit7 = setupSimPar("SIM_EMRG");
|
|
}
|
|
// in emergenza: provo split ODL
|
|
trySplitOdl();
|
|
}
|
|
else if (bit4.wait <= 0)
|
|
{
|
|
// segnalo BIT
|
|
B_input += (1 << 4);
|
|
// decremento duration
|
|
bit4.duration--;
|
|
// controllo se sia scaduta la duration... in quel caso reset...
|
|
if (bit4.duration <= 0)
|
|
{
|
|
bit4 = setupSimPar("SIM_MANU");
|
|
}
|
|
// in manuale: provo split ODL
|
|
trySplitOdl();
|
|
}
|
|
else if (bit2.wait <= 0)
|
|
{
|
|
// salvo nuovo contapezziPLC
|
|
var rand = new Random();
|
|
// se online vero delta (0..3) altrimenti 1
|
|
int delta = IobOnline ? rand.Next(1, 4) : 1;
|
|
if (!isMulti)
|
|
{
|
|
// solo se MP online...
|
|
if (MPOnline)
|
|
{
|
|
contapezziPLC += delta;
|
|
lgInfo($"S01: Valori contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB} | aggiunto delta {delta}");
|
|
}
|
|
}
|
|
// SOLO SE sono online...
|
|
if (IobOnline)
|
|
{
|
|
// se multipallet --> cP a zero!
|
|
if (isMulti)
|
|
{
|
|
cP = 0;
|
|
}
|
|
// se NON Multi fa contapezzi...
|
|
else
|
|
{
|
|
// SE NON SONO GIA' OLTRE il contapezzi
|
|
if (contapezziIOB < contapezziPLC)
|
|
{
|
|
// segnalo BIT (1 pz)
|
|
B_input += (1 << 2);
|
|
}
|
|
}
|
|
// decremento duration
|
|
bit2.duration--;
|
|
// controllo se sia scaduta la duration... in quel caso reset...
|
|
if (bit2.duration <= 0)
|
|
{
|
|
bit2 = setupSimPar("SIM_PZCNT");
|
|
// salvo nuovo contapezzi (incremento di 1...) + richiesta refresh conteggio
|
|
contapezziIOB++;
|
|
needRefreshPzCount = true;
|
|
lgInfo($"S01: Valori contatori: contapezzi macchina contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB} - incremento contapezzi per bit2.duration <= 0");
|
|
// invio SOLO SE il contapezzi PLC è <= contapezzi IOB...
|
|
if (contapezziPLC <= contapezziIOB)
|
|
{
|
|
sendContapezzi = true;
|
|
}
|
|
}
|
|
if (sendContapezzi)
|
|
{
|
|
// controllo se ALMENO sia pingabile il server
|
|
if (checkServerAlive)
|
|
{
|
|
// invio a server contapezzi (aggiornato)
|
|
string retVal = utils.callUrl(urlSetPzCount + contapezziIOB.ToString());
|
|
// verifica se tutto OK
|
|
if (retVal != contapezziIOB.ToString())
|
|
{
|
|
// errore salvataggio contapezzi
|
|
lgInfo($"Errore salvataggio Contapezzi SIMULA 03: contapezziIOB {contapezziIOB} | risposta: {retVal}");
|
|
// se non sono multi...
|
|
if (!isMulti)
|
|
{
|
|
// rileggo il counter pezzi da server
|
|
pzCntReload(true);
|
|
}
|
|
}
|
|
// resetto timer...
|
|
lastPzCountSend = DateTime.Now;
|
|
}
|
|
}
|
|
// provo a fare split ODL SE NON E' multi....
|
|
trySplitOdl();
|
|
}
|
|
else
|
|
{
|
|
// decremento duration
|
|
bit2.duration--;
|
|
if (bit2.duration <= 0)
|
|
{
|
|
bit2 = setupSimPar("SIM_PZCNT");
|
|
}
|
|
}
|
|
}
|
|
else if (bit5.wait <= 0 || tcMan.alarmDelayTC)
|
|
{
|
|
// segnalo BIT
|
|
B_input += (1 << 5);
|
|
// decremento duration
|
|
bit5.duration--;
|
|
// controllo se sia scaduta la duration... in quel caso reset...
|
|
if (bit5.duration <= 0)
|
|
{
|
|
bit5 = setupSimPar("SIM_SLOW");
|
|
}
|
|
}
|
|
// se multi gestisco il bit delle tavole...
|
|
if (isMulti)
|
|
{
|
|
// se sono in fase di fronte d'uscita (invio contapezzi) INVERTO nP...
|
|
if (sendContapezzi)
|
|
{
|
|
nP = nP == 1 ? 2 : 1;
|
|
// assegno a cP il valore nP...
|
|
cP = nP;
|
|
contapezziPLC++;
|
|
}
|
|
// se cP > 0 --> segnalo bit tavola...
|
|
if (cP == 1)
|
|
{
|
|
B_input += (1 << 8);
|
|
}
|
|
else if (cP == 2)
|
|
{
|
|
B_input += (1 << 9);
|
|
}
|
|
}
|
|
|
|
// init obj display
|
|
newDisplayData currDispData = new newDisplayData();
|
|
currDispData.counter = contapezziIOB;
|
|
currDispData.semOut = Semaforo.SV;
|
|
raiseRefresh(currDispData);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Setup aprametri di simulazione per BIT indicato
|
|
/// </summary>
|
|
/// <param name="keyName"></param>
|
|
private simPar setupSimPar(string keyName)
|
|
{
|
|
simPar answ = new simPar();
|
|
if (cIobConf.optPar.Count > 0)
|
|
{
|
|
if (cIobConf.optPar.ContainsKey(keyName))
|
|
{
|
|
string fullVal = getOptPar(keyName);
|
|
if (!string.IsNullOrEmpty(fullVal) && fullVal.IndexOf("|") > 0)
|
|
{
|
|
string[] param = fullVal.Split('|');
|
|
int.TryParse(param[0], out answ.wait);
|
|
int.TryParse(param[1], out answ.duration);
|
|
// aggiongo noise, +/- 40%...
|
|
Random rnd = new Random();
|
|
int noise = rnd.Next(1, answ.wait * 40 / 100);
|
|
answ.wait += noise - (answ.wait * 20 / 100);
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// provo a chiamare split ODL
|
|
/// </summary>
|
|
private void trySplitOdl()
|
|
{
|
|
if (!isMulti)
|
|
{
|
|
// solo se ODL è in lavorazione da ALMENO minDurataODL minuti...
|
|
DateTime inizioOdl = DateTime.Now.AddDays(-1);
|
|
string rawDataInizio = callUrl(urlInizioOdlIob, false);
|
|
DateTime.TryParse(rawDataInizio, out inizioOdl);
|
|
if (DateTime.Now.Subtract(inizioOdl).TotalMinutes > minDurataODL)
|
|
{
|
|
// invio reset ODL...
|
|
forceSplitOdl();
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Private Methods
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// Salvo valori PLC
|
|
/// </summary>
|
|
/// <param name="updatedPar"></param>
|
|
protected override void plcWriteParams(List<objItem> updatedPar)
|
|
{
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Processo i task richiesti e li elimino dalla coda 1:1 (in realtà SOLO forceSetPzCount x ora)
|
|
/// </summary>
|
|
/// <param name="task2exe"></param>
|
|
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
|
{
|
|
// Verificare il protocollo: dovrebeb togliere SOLO i task eseguiti...
|
|
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
|
string taskVal = "";
|
|
// verifico non sia null
|
|
if (task2exe != null)
|
|
{
|
|
// cerco task specifici
|
|
foreach (var item in task2exe)
|
|
{
|
|
taskVal = "";
|
|
// converto richiesta in enum...
|
|
taskType tName = taskType.nihil;
|
|
Enum.TryParse(item.Key, out tName);
|
|
// controllo sulla KEY
|
|
switch (tName)
|
|
{
|
|
case taskType.setArt:
|
|
case taskType.setComm:
|
|
case taskType.setProg:
|
|
case taskType.setPzComm:
|
|
memMap.mMapWrite[item.Key].value = item.Value;
|
|
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | UPDATED memMap.mMapWrite";
|
|
break;
|
|
|
|
case taskType.setParameter:
|
|
// richiedo da URL i parametri WRITE da popolare
|
|
lgInfo("Chiamata processMemWriteRequests");
|
|
taskVal = processMemWriteRequests();
|
|
// se restituiscce "" faccio altra prova...
|
|
if (string.IsNullOrEmpty(taskVal))
|
|
{
|
|
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
|
if (item.Value.Contains("|"))
|
|
{
|
|
string[] paramsJob = item.Value.Split('|');
|
|
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
|
}
|
|
else
|
|
{
|
|
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
|
|
}
|
|
}
|
|
break;
|
|
|
|
case taskType.nihil:
|
|
case taskType.fixStopSetup:
|
|
case taskType.forceResetPzCount:
|
|
case taskType.sendWatchDogMes2Plc:
|
|
case taskType.startSetup:
|
|
case taskType.stopSetup:
|
|
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
|
break;
|
|
|
|
case taskType.forceSetPzCount:
|
|
// forzo sul SIM il valore pzCount dell'IOB...
|
|
int newPzCount = contapezziPLC;
|
|
bool fatto = int.TryParse(item.Value, out newPzCount);
|
|
if (fatto)
|
|
{
|
|
// verifico SE sia ammesso il cambio ...
|
|
int deltaPzCount = newPzCount - contapezziPLC;
|
|
double maxDelta = DateTime.Now.Subtract(plcLastPzRead).TotalMinutes / (plcAvgTc / 60);
|
|
// se incremento superiore del doppio atteso --> segnalo errore e NON accetto
|
|
if (deltaPzCount > (maxDelta * maxPzDeltaPerc) / 100)
|
|
{
|
|
lgError($"[DELTA CHECK]: intremento contapezziPLC troppo elevato: lettura {newPzCount} | contapezzi attuale: {contapezziPLC} | ultima lettura PLC: {plcLastPzRead} | TCiclo medio: {plcAvgTc}s | incremento accettato ");
|
|
}
|
|
else
|
|
{
|
|
contapezziPLC = newPzCount;
|
|
taskVal = $"Set new contapezziPLC: {contapezziPLC}";
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
taskVal = "SKIPPED | NO EXEC";
|
|
break;
|
|
}
|
|
// aggiungo task!
|
|
taskDone.Add(item.Key, taskVal);
|
|
}
|
|
}
|
|
|
|
return taskDone;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera e processa allarmi CNC...
|
|
/// </summary>
|
|
public override Dictionary<string, string> getCncAlarms()
|
|
{
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
return outVal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero dati dinamici...
|
|
/// </summary>
|
|
public override Dictionary<string, string> getDynData()
|
|
{
|
|
// valore non presente in vers default... se gestito fare override
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
// verificare periodo SIM parametri... se passato li invio altrimenti NO... FIX a 20 sec
|
|
if (lastSimData.AddSeconds(waitSimPar) < DateTime.Now)
|
|
{
|
|
Random rnd = new Random();
|
|
// controllo conf memorie json (se ci sono...)
|
|
try
|
|
{
|
|
if (memMap.mMapWrite.Count > 0)
|
|
{
|
|
foreach (var item in memMap.mMapWrite)
|
|
{
|
|
outVal.Add(item.Key, item.Value.value);
|
|
}
|
|
}
|
|
if (memMap.mMapRead.Count > 0)
|
|
{
|
|
foreach (var item in memMap.mMapRead)
|
|
{
|
|
// uso factor come valore MAX ammesso
|
|
int randVal = rnd.Next((int)item.Value.minVal, (int)item.Value.maxVal);
|
|
outVal.Add(item.Key, randVal.ToString());
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
lastSimData = DateTime.Now;
|
|
}
|
|
return outVal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero programma in lavorazione
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override string getPrgName()
|
|
{
|
|
// valore non presente in vers default... se gestito fare override
|
|
string prgName = string.Format("DEMO_{0:00}", DateTime.Now.Minute);
|
|
return prgName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero info sistema generiche
|
|
/// <returns></returns>
|
|
public override Dictionary<string, string> getSysInfo()
|
|
{
|
|
// valore non presente in vers default... se gestito fare override
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
outVal.Add("MACHINE", "IOB_SIM");
|
|
return outVal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua vero processing contapezzi
|
|
/// </summary>
|
|
public override void processContapezzi()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processo contatori eventi...
|
|
/// </summary>
|
|
public override void processVHF()
|
|
{
|
|
if (lastEvCheck.AddMilliseconds(periodoMSec) < DateTime.Now)
|
|
{
|
|
// decremento contatore ultimo evento
|
|
bit2.wait--;
|
|
bit3.wait--;
|
|
bit4.wait--;
|
|
bit5.wait--;
|
|
lastEvCheck = DateTime.Now;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua lettura semafori principale
|
|
/// <paramref name="currDispData">Parametri da aggiornare x display in form</paramref>
|
|
/// </summary>
|
|
public override void readSemafori(ref newDisplayData currDispData)
|
|
{
|
|
base.readSemafori(ref currDispData);
|
|
// decodifica e gestione
|
|
decodeToBaseBitmap();
|
|
decodeOtherData();
|
|
reportRawInput(ref currDispData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua reset del contapezzi
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool resetContapezziPLC()
|
|
{
|
|
bool answ = false;
|
|
// ...SE abilitato da conf IOB
|
|
if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE")
|
|
{
|
|
// fingo di aver fatto...
|
|
answ = true;
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
public override void tryConnect()
|
|
{
|
|
base.tryConnect();
|
|
connectionOk = true;
|
|
}
|
|
|
|
public override void tryDisconnect()
|
|
{
|
|
base.tryDisconnect();
|
|
connectionOk = false;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configuraizone eventi da simulare
|
|
/// </summary>
|
|
public class simPar
|
|
{
|
|
#region Public Fields
|
|
|
|
/// <summary>
|
|
/// Durata dell'evento
|
|
/// </summary>
|
|
public int duration = 1;
|
|
|
|
/// <summary>
|
|
/// DateTime ultimo evento
|
|
/// </summary>
|
|
public DateTime lastEv = DateTime.Now;
|
|
|
|
/// <summary>
|
|
/// Attesa per evento
|
|
/// </summary>
|
|
public int wait = 10;
|
|
|
|
#endregion Public Fields
|
|
}
|
|
} |