Completato fix metodo AutoODL (da testare!)

This commit is contained in:
Samuele Locatelli
2026-04-17 08:55:00 +02:00
parent c0552e87a8
commit cf060cc387
8 changed files with 693 additions and 7 deletions
+1
View File
@@ -78,6 +78,7 @@ namespace MP.Core
public const string redisTipoArt = redisBaseAddr + "Cache:TipoArt";
public const string redisVetoSplitOdl = redisBaseAddr + "Cache:VetoOdlMacc";
public const string redisVocabolario = redisBaseAddr + "Cache:Vocabolario";
public const string redisXdlData = redisBaseAddr + "Cache:XDL:";
+225 -1
View File
@@ -96,6 +96,140 @@ namespace MP.Data.Controllers
return dbResult;
}
/// <summary>
/// Apre in automatico un nuovo PODL/ODL chiudendo l'attuale (aperto)
/// </summary>
/// <param name="idxOdl">Idx ODL corrente</param>
/// <param name="MatrOpr">Matricola operatore</param>
/// <param name="idxMacchina">idx macchina da confermare</param>
/// <param name="tCRich">TempoCiclo richiesto in attrezzaggio</param>
/// <param name="pzPallet"># pz pallet</param>
/// <param name="note">note ODL</param>
/// <param name="startNewOdl">bool per avvio nuovo ODL (def: true)</param>
/// <param name="qtyRich">Qty da produrre, deve essere >0</param>
/// <param name="keyRich">KeyRich esterno, se vuoto uso vecchia, se KIT sovrascritto con KeyKit</param>
/// <returns></returns>
public async Task<bool> AutoStartOdlAsync(int idxOdl, int MatrOpr, string idxMacchina, decimal tCRich, int pzPallet, string note, bool startNewOdl, int qtyRich, string keyRich)
{
bool answ = false;
try
{
using (var dbCtx = new MoonProContext(_configuration))
{
var IdxOdl = new SqlParameter("@idxOdl ", idxOdl);
var MatrApp = new SqlParameter("@MatrApp ", MatrOpr);
var IdxMacchina = new SqlParameter("@idxMacchina", idxMacchina);
var TCRich = new SqlParameter("@TCRichAttr", tCRich);
var PzPallet = new SqlParameter("@PzPallet", pzPallet);
var Note = new SqlParameter("@Note", note);
var StartNewOdl = new SqlParameter("@StartNewOdl", startNewOdl);
var QtyRich = new SqlParameter("@QtyRich", qtyRich);
var KeyRichiesta = new SqlParameter("@KeyRichiesta", keyRich);
var result = await dbCtx
.Database
.ExecuteSqlRawAsync("EXEC stp_ODL_AutoStart @idxOdl, @MatrApp, @idxMacchina, @TCRichAttr, @PzPallet, @Note, @StartNewOdl, @QtyRich, @KeyRichiesta", IdxOdl, MatrApp, IdxMacchina, TCRich, PzPallet, Note, StartNewOdl, QtyRich, KeyRichiesta);
// indico eseguito!
answ = result > 0;
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in ConfermaProdMacchina:{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma - dtEvent)
/// </summary>
/// <param name="idxMacchina">idx macchina da confermare</param>
/// <param name="modoConfProd">0=periodo, 1 = giorno, 2 = turno</param>
/// <param name="numPzConfermati">qta pezzi BUONI da confermare</param>
/// <param name="numPzScarto">qta pezzi SCARTO da confermare</param>
/// <param name="DataOraApp">DataOra in cui registrare approvazione</param>
/// <param name="MatrOpr">Matricola operatore</param>
/// <returns></returns>
public async Task<bool> ConfermaProdMacchinaAsync(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzScarto, DateTime DataOraApp, int MatrOpr)
{
bool answ = false;
try
{
var rigaProd = await StatoProdMacchinaAsync(idxMacchina, DateTime.Now);
using (var dbCtx = new MoonProContext(_configuration))
{
var IdxMacchina = new SqlParameter("@idxMacchina", idxMacchina);
var MatrApp = new SqlParameter("@MatrApp ", MatrOpr);
var DataFrom = new SqlParameter("@dataFrom ", rigaProd.DataFrom);
var DataTo = new SqlParameter("@dataTo", DataOraApp);
var PezziConf = new SqlParameter("@pezziConf", numPzConfermati);
var PezziScar = new SqlParameter("@pezziScar", numPzScarto);
var TipoConf = new SqlParameter("@TipoConf", modoConfProd);
var DtOraApp = new SqlParameter("@DataOraApp", DataOraApp);
var TestConferma = new SqlParameter("@TestConferma", true);
var result = await dbCtx
.Database
.ExecuteSqlRawAsync("EXEC stp_ConfermaProduzCompleta @idxMacchina, @MatrApp, @dataFrom, @dataTo, @pezziConf, @pezziScar, @TipoConf, @DataOraApp, @TestConferma ", IdxMacchina, MatrApp, DataFrom, DataTo, PezziConf, PezziScar, TipoConf, DtOraApp, TestConferma);
// indico eseguito!
answ = result > 0;
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in ConfermaProdMacchina:{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma - dtEvent)
/// </summary>
/// <param name="idxMacchina">idx macchina da confermare</param>
/// <param name="modoConfProd">0=periodo, 1 = giorno, 2 = turno</param>
/// <param name="numPzConfermati">qta pezzi BUONI da confermare</param>
/// <param name="numPzLasciati">qta pezzi LASCIATI da confermare</param>
/// <param name="numPzScarto">qta pezzi SCARTO da confermare</param>
/// <param name="DataOraApp">DataOra in cui registrare approvazione</param>
/// <param name="MatrOpr">Matricola operatore</param>
/// <returns></returns>
public async Task<bool> ConfermaProdMacchinaFullAsync(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzLasciati, int numPzScarto, DateTime DataOraApp, int MatrOpr)
{
bool answ = false;
try
{
var rigaProd = await StatoProdMacchinaAsync(idxMacchina, DateTime.Now);
using (var dbCtx = new MoonProContext(_configuration))
{
var IdxMacchina = new SqlParameter("@idxMacchina", idxMacchina);
var MatrApp = new SqlParameter("@MatrApp ", MatrOpr);
var DataFrom = new SqlParameter("@dataFrom ", rigaProd.DataFrom);
var DataTo = new SqlParameter("@dataTo", DataOraApp);
var PezziConf = new SqlParameter("@pezziConf", numPzConfermati);
var PezziLasc = new SqlParameter("@pezziLasciati", numPzLasciati);
var PezziScar = new SqlParameter("@pezziScar", numPzScarto);
var TipoConf = new SqlParameter("@TipoConf", modoConfProd);
var DtOraApp = new SqlParameter("@DataOraApp", DataOraApp);
var TestConferma = new SqlParameter("@TestConferma", true);
var Force = new SqlParameter("@Force", false);
var result = await dbCtx
.Database
.ExecuteSqlRawAsync("EXEC stp_ConfermaProduzCompletaFull @idxMacchina, @MatrApp, @dataFrom, @dataTo, @pezziConf, @pezziLasciati, @pezziScar, @TipoConf, @DataOraApp, @TestConferma,@Force", IdxMacchina, MatrApp, DataFrom, DataTo, PezziConf, PezziLasc, PezziScar, TipoConf, DtOraApp, TestConferma, Force);
// indico eseguito!
answ = result > 0;
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in ConfermaProdMacchinaAsync:{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Record ConfFlux dato macchina (oppure tutti se vuoto)
/// </summary>
@@ -326,6 +460,65 @@ namespace MP.Data.Controllers
}
return fatto;
}
/// <summary>
/// Fix ODL per macchine SLAVE
/// </summary>
/// <param name="idxMacchina"></param>
/// <param name="numDayPrev"></param>
/// <param name="doInsert"></param>
/// <returns></returns>
public bool OdlFixMachineSlave(string idxMacchina, int numDayPrev, int doInsert)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina);
var NumDayPrev = new SqlParameter("@NumDayPrev", numDayPrev);
var DoInsert = new SqlParameter("@DoInsert", doInsert);
var result = dbCtx
.Database
.ExecuteSqlRaw("EXEC stp_ODL_fixMachineSlave @IdxMacchina, @NumDayPrev, @DoInsert", IdxMacc, NumDayPrev, DoInsert);
fatto = result != 0;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante OdlFixMachineSlave{Environment.NewLine}{exc}");
}
}
return fatto;
}
/// <summary>
/// Fix ODL per macchine SLAVE Async
/// </summary>
/// <param name="idxMacchina"></param>
/// <param name="numDayPrev"></param>
/// <param name="doInsert"></param>
/// <returns></returns>
public async Task<bool> OdlFixMachineSlaveAsync(string idxMacchina, int numDayPrev, int doInsert)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina);
var NumDayPrev = new SqlParameter("@NumDayPrev", numDayPrev);
var DoInsert = new SqlParameter("@DoInsert", doInsert);
var result = await dbCtx
.Database
.ExecuteSqlRawAsync("EXEC stp_ODL_fixMachineSlave @IdxMacchina, @NumDayPrev, @DoInsert", IdxMacc, NumDayPrev, DoInsert);
fatto = result != 0;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante OdlFixMachineSlaveAsync{Environment.NewLine}{exc}");
}
}
return fatto;
}
/// <summary>
/// Chiamata x stored recupero FluxLog x macchina (first)
@@ -1130,7 +1323,38 @@ namespace MP.Data.Controllers
}
catch (Exception exc)
{
Log.Error($"Eccezione in RicalcMse:{Environment.NewLine}{exc}");
Log.Error($"Eccezione in RecalcMse:{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Effettua ricalcolo MSE x macchina indicata
/// </summary>
/// <param name="idxMacchina">idx macchina da confermare</param>
/// <param name="maxAgeSec">Num massimo secondi di "vecchiaia" del dato</param>
/// <returns></returns>
public async Task<bool> RecalcMseAsync(string idxMacchina, int maxAgeSec)
{
bool answ = false;
try
{
var rigaProd = await StatoProdMacchinaAsync(idxMacchina, DateTime.Now);
using (var dbCtx = new MoonProContext(_configuration))
{
var MaxAgeSec = new SqlParameter("@maxAgeSec ", maxAgeSec);
var IdxMacchina = new SqlParameter("@idxMacchina", idxMacchina);
var result = await dbCtx
.Database
.ExecuteSqlRawAsync("EXEC stp_MSE_recalc @maxAgeSec, @idxMacchina ", MaxAgeSec, IdxMacchina);
// indico eseguito!
answ = result > 0;
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in RecalcMseAsync:{Environment.NewLine}{exc}");
}
return answ;
}
+31
View File
@@ -326,6 +326,37 @@ namespace MP.IOC.Controllers
}
}
/// <summary>
/// Chiude ODL precedente ed avvia uno nuovo (duplicandolo e sitemando quantità RIMANENTE),
/// e CONFERMA produzione...
///
/// GET: IOB/forceSplitOdl/SIMUL_03
/// </summary>
/// <param name="id"></param>
/// <returns>Esito chiamata (OK/vuoto)</returns>
[HttpGet("forceSplitOdl/{id}")]
public async Task<IActionResult> ForceSplitOdl(string id)
{
if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID");
// Multi: gestione carattere "|" trasformato in "#"
id = id.Replace("|", "#");
string answ = "";
try
{
answ = await DService.AutoStartOdlAsync(id, true, true, 100, 0, "");
}
catch (Exception exc)
{
Log.Error($"Errore in ForceSplitOdl{Environment.NewLine}{exc}");
return StatusCode(StatusCodes.Status500InternalServerError, "NO");
}
return Ok(answ);
}
/// <summary>
/// Recupera ArtNum dato CodXdl (per impianti che accettano solo INT in scrittura):
/// GET: IOB/getArtNum/SIMUL_03?CodXdl=ABC123
+432 -2
View File
@@ -246,6 +246,70 @@ namespace MP.IOC.Data
return answ;
}
/// <summary>
/// Aggiunge un set di task x macchina all'elenco di quelli salvati (in modalità upsert)
/// </summary>
/// <param name="idxMacchina"></param>
/// <param name="taskKey"></param>
/// <param name="taskVal"></param>
/// <returns></returns>
public async Task<bool> AddTask4MacListAsync(string idxMacchina, Dictionary<Enums.taskType, string> taskDict)
{
bool answ = false;
bool needSaveParams = false;
var currHash = Utils.RedKeyTask2ExeMacc(idxMacchina, MpIoNS);
var currSavedParHash = Utils.RedKeySavedTask2ExeMacc(idxMacchina, MpIoNS);
Dictionary<string, string> currTask = new Dictionary<string, string>();
Dictionary<string, string> savedTask = new Dictionary<string, string>();
// leggo valori attuali...
currTask = await mTaskMacchinaAsync(idxMacchina);
// verifico processing dei ricevuti
foreach (var item in taskDict)
{
if (currTask.ContainsKey($"{item.Key}"))
{
currTask[$"{item.Key}"] = item.Value;
}
else
{
currTask.Add($"{item.Key}", item.Value);
}
Log.Trace($"Task ADD | hash: {currHash} | idxMacchina: {idxMacchina} | taskKey: {item.Key} | taskVal: {item.Value}");
// verifico in base al tipo di tName se fare backup...
switch (item.Key)
{
case Enums.taskType.setArt:
case Enums.taskType.setComm:
case Enums.taskType.setPzComm:
case Enums.taskType.setProg:
// leggo tName SALVATI attuali...
savedTask = mSavedTaskMacchina(idxMacchina);
savedTask[item.Key.ToString()] = item.Value;
needSaveParams = true;
break;
case Enums.taskType.endProd:
// salvo un DICT vuoto x resettare
savedTask = new Dictionary<string, string>();
needSaveParams = true;
break;
default:
break;
}
}
// salvo!
answ = await RedisSetHashDictAsync(currHash, currTask);
if (needSaveParams)
{
answ = await RedisSetHashDictAsync(currSavedParHash, savedTask);
}
return answ;
}
/// <summary>
/// Insert record allarme
/// </summary>
@@ -549,6 +613,308 @@ namespace MP.IOC.Data
return answ;
}
/// <summary>
/// Effettua split ODL
/// </summary>
/// <param name="idxMacchina">macchina</param>
/// <param name="doConfirm">effettuare conferma qty</param>
/// <param name="qtyFromLast">imposta la qty prox ODL da ODL che si chiude</param>
/// <param name="matrOpr">matricola operatore</param>
/// <param name="roundStep">Round Step quantità prox ODL (corrente come riferimento)</param>
/// <param name="keyRichiesta">Cod ext da associare all'ODL</param>
/// <returns></returns>
public async Task<string> AutoStartOdlAsync(string idxMacchina, bool doConfirm, bool qtyFromLast, int matrOpr, int roundStep = 100, string keyRichiesta = "")
{
string answ = "KO";
DateTime adesso = DateTime.Now;
// verifico NON CI SIA un veto a NUOVI split...
string redKey = $"{Utils.redisVetoSplitOdl}:{idxMacchina}";
var rawData = await redisDb.StringGetAsync(redKey);
if (rawData.HasValue)
{
Log.Info($"VETO ATTIVO | Richiesto forceSplitOdl per impianto {idxMacchina} | impossibile procedere");
}
else
{
// registro VETO x altri split... 5 minuti
await redisDb.StringSetAsync(redKey, $"Inizio SPLIT-ODL {adesso}", TimeSpan.FromMinutes(5));
// setup dati da config
bool confRett = false;
int modoConfProd = -1;
bool slaveConfirmPzProd = false;
var configData = await ConfigGetAllAsync();
if (configData != null)
{
var currRec = configData.FirstOrDefault(x => x.Chiave == "confRett");
if (currRec != null)
{
bool.TryParse(currRec.Valore, out confRett);
}
currRec = configData.FirstOrDefault(x => x.Chiave == "modoConfProd");
if (currRec != null)
{
int.TryParse(currRec.Valore, out modoConfProd);
}
currRec = configData.FirstOrDefault(x => x.Chiave == "SlaveConfirmPzProd");
if (currRec != null)
{
bool.TryParse(currRec.Valore, out slaveConfirmPzProd);
}
}
// calcolo la qta da gestire
int qtyConf = 0;
int qtyNew = 0;
int qtyScarto = 0;
if (doConfirm)
{
try
{
var rigaProd = await IocDbController.PezziProdMacchinaAsync(idxMacchina);
var statoProd = await IocDbController.StatoProdMacchinaAsync(idxMacchina, adesso);
qtyConf = rigaProd.pezziNonConfermati;
qtyScarto = statoProd.Pz2RecScarto;
// calcolo nuovi pezzi da confermare
if (qtyFromLast)
{
roundStep = roundStep == 0 ? 1 : roundStep;
double ratio = (double)qtyConf / roundStep;
qtyNew = (int)Math.Round(Math.Ceiling(ratio) * roundStep, 0);
}
}
catch (Exception exc)
{
Log.Error($"AutoStartOdlAsync | Errore recupero pezzi da confermare | idxMacchina {idxMacchina}{Environment.NewLine}{exc}");
}
}
// chiamo metodo redis/db...
try
{
// recupero ODL corrente
var currData = await IocDbController.OdlCurrByMaccAsync(idxMacchina);
if (currData != null && currData.IdxOdl > 0)
{
// preparo var x master/slave
bool isMachMaster = await IobIsMasterAsync(idxMacchina);
List<Macchine2SlaveModel> slaveList = new();
if (isMachMaster)
{
List<Macchine2SlaveModel> allSlaveList = await IocDbController.Macchine2SlaveAsync();
slaveList = allSlaveList.Where(x => x.IdxMacchina == idxMacchina).ToList();
}
// registro un evento di inizio attrezzaggio (idxTipoEv = 2)
int idxEvento = 2;
Log.Info($"Invio evento ODL-SPLIT per macchina {idxMacchina} | ev: {idxEvento} | art: {currData.CodArticolo} | qty conf: {qtyConf} | sty sca: {qtyScarto} | new qty: {qtyNew}");
// creo evento
EventListModel newRecEv = new EventListModel()
{
CodArticolo = currData.CodArticolo,
IdxMacchina = idxMacchina,
IdxTipo = idxEvento,
InizioStato = adesso,
MatrOpr = matrOpr,
pallet = "",
Value = "ODL-SPLIT"
};
inputComandoMapo resCmd = await scriviRigaEventoBarcodeAsync(newRecEv);
// era 100, messo 50...
int wTime = 50;
// eventuale conferma produzione
if (doConfirm)
{
await Task.Delay(wTime);
adesso = DateTime.Now;
// chiamo conferma produzione...
try
{
string chiamata = confRett ? "confermaProdMacchinaFull" : "confermaProdMacchina";
Log.Info($"Chiamata a {chiamata} con parametri {currData.IdxMacchina} |{matrOpr} | {DateTime.Now.AddDays(-10)} | {DateTime.Now} | {qtyConf} | 0 | {qtyScarto} | {DateTime.Now} | false");
string idxMacchinaSel = currData.IdxMacchina;
bool fatto = false;
if (confRett)
{
// confermo al netto dei pezzi lasciati...
fatto = await IocDbController.ConfermaProdMacchinaFullAsync(idxMacchinaSel, modoConfProd, qtyConf, 0, qtyScarto, adesso, matrOpr);
if (slaveConfirmPzProd)
{
foreach (var machine in slaveList)
{
await IocDbController.ConfermaProdMacchinaFullAsync(machine.IdxMacchinaSlave, modoConfProd, qtyConf, 0, qtyScarto, adesso, matrOpr);
}
}
}
else
{
fatto = await IocDbController.ConfermaProdMacchinaAsync(idxMacchinaSel, modoConfProd, qtyConf, qtyScarto, adesso, matrOpr);
if (slaveConfirmPzProd)
{
foreach (var machine in slaveList)
{
await IocDbController.ConfermaProdMacchinaAsync(idxMacchinaSel, modoConfProd, qtyConf, qtyScarto, adesso, matrOpr);
}
}
}
if (!fatto)
{
Log.Error($"ERRORE in chiamata {chiamata}");
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in ConfermaProduzione{Environment.NewLine}{exc}");
}
}
// 2025.02.19 portato da 100 a 1000 ms attesa x evitare che ODL sia avviato PRIMA della conferma
// attendo 1000 msec x chiudere ODL
await Task.Delay(1000);
// chiamo splitOdl
await IocDbController.AutoStartOdlAsync(currData.IdxOdl, 0, idxMacchina, currData.TCRichAttr, currData.PzPallet, $"Nuovo ODL da forceSplitOdl.autoStart", true, qtyNew, keyRichiesta);
// elimino eventuale ODL precedente...
string currKey = $"{Utils.redisOdlCurrByMac}:{idxMacchina}";
await redisDb.KeyDeleteAsync(currKey);
// ricalcola ODL macchina
var newOdl = await GetCurrOdlAsync(idxMacchina);
// attendo 1000 msec
await Task.Delay(1000);
adesso = DateTime.Now;
// registro fine ODL (idxTipoEv = 1)
idxEvento = 1;
Log.Info($"Invio evento FINE ODL-SPLIT | idx: {idxMacchina} | ev: {idxEvento} | art: {currData.CodArticolo}");
// costruisco nuovo evento
newRecEv = new EventListModel()
{
CodArticolo = currData.CodArticolo,
IdxMacchina = idxMacchina,
IdxTipo = idxEvento,
InizioStato = adesso,
MatrOpr = matrOpr,
pallet = "",
Value = "ODL-START"
};
resCmd = await scriviRigaEventoBarcodeAsync(newRecEv);
// invio eventi setup a macchina....
string setArtVal = $"{currData.CodArticolo}";
string setPzCommVal = $"{qtyNew}";
string setCommVal = $"ODL{newOdl}";
if (!string.IsNullOrEmpty(keyRichiesta))
{
setCommVal = $"{keyRichiesta} ODL{newOdl}";
}
try
{
// invio task caricamento dati ODL
Dictionary<taskType, string> updDict = new Dictionary<taskType, string>();
updDict.Add(taskType.setArt, setArtVal);
updDict.Add(taskType.setComm, setCommVal);
updDict.Add(taskType.setPzComm, setPzCommVal);
#if false
addTask4Machine(idxMacchina, taskType.setArt, setArtVal);
addTask4Machine(idxMacchina, taskType.setComm, setCommVal);
addTask4Machine(idxMacchina, taskType.setPzComm, setPzCommVal);
updateMachineParameter(idxMacchina, "setArt", setArtVal);
updateMachineParameter(idxMacchina, "setComm", setCommVal);
updateMachineParameter(idxMacchina, "setPzComm", setPzCommVal);
#endif
// recupero set attuale parametri
var currMachPar = await MachineParamListAsync(idxMacchina);
List<ObjItemDTO> list2upd = new();
// aggiorno i valori interessati tra quelli nel dizionario
foreach (var item in updDict)
{
var cRec = currMachPar.FirstOrDefault(x => x.uid == $"{item.Key}");
if (cRec != null)
{
list2upd.Add(cRec);
}
}
// aggiungo task di setParameters x la commessa...
updDict.Add(taskType.setParameter, setCommVal);
// salvo
await AddTask4MacListAsync(idxMacchina, updDict);
await MachineParamUpsertAsync(idxMacchina, list2upd);
}
catch
{ }
// chiamo refresh MSE
await IocDbController.RecalcMseAsync(idxMacchina, 0);
// resetto stato macchina...
var kStatoMacc = $"{Utils.redisStatoMacch}:{idxMacchina}";
await redisDb.KeyDeleteAsync(kStatoMacc);
answ = "OK";
Log.Info($"Effettuato reset e ricalcoli x split ODL per macchina {idxMacchina}");
// se è una master richiamo fix x child...
if (isMachMaster)
{
Dictionary<taskType, string> updDict = new Dictionary<taskType, string>();
string ts = "";
string outData = "";
await IocDbController.OdlFixMachineSlaveAsync(idxMacchina, 30, 1);
foreach (var machine in slaveList)
{
// invio chiusura attrezzaggio
ts = string.Format("{0:yyMMdd}T{0:HHmmss.fff}Z", DateTime.Now);
outData = $"TS:{ts}|MATR:{matrOpr}|ODL:{newOdl}";
updDict.Clear();
updDict.Add(taskType.setArt, setArtVal);
updDict.Add(taskType.setComm, setCommVal);
updDict.Add(taskType.setPzComm, setPzCommVal);
#if false
addTask4Machine(machine.IdxMacchinaSlave, taskType.fixStopSetup, outData);
addTask4Machine(machine.IdxMacchinaSlave, taskType.forceResetPzCount, outData);
// invio task caricamento dati ODL
addTask4Machine(machine.IdxMacchinaSlave, taskType.setArt, setArtVal);
addTask4Machine(machine.IdxMacchinaSlave, taskType.setComm, setCommVal);
addTask4Machine(machine.IdxMacchinaSlave, taskType.setPzComm, setPzCommVal);
updateMachineParameter(machine.IdxMacchinaSlave, "setArt", setArtVal);
updateMachineParameter(machine.IdxMacchinaSlave, "setComm", setCommVal);
updateMachineParameter(machine.IdxMacchinaSlave, "setPzComm", setPzCommVal);
#endif
// recupero set attuale parametri
var currMachPar = await MachineParamListAsync(machine.IdxMacchinaSlave);
List<ObjItemDTO> list2upd = new();
// aggiorno i valori interessati tra quelli nel dizionario
foreach (var item in updDict)
{
var cRec = currMachPar.FirstOrDefault(x => x.uid == $"{item.Key}");
if (cRec != null)
{
list2upd.Add(cRec);
}
}
// aggiungo task di setParameters x la commessa...
updDict.Add(taskType.fixStopSetup, outData);
updDict.Add(taskType.forceResetPzCount, outData);
updDict.Add(taskType.setParameter, setCommVal);
// salvo
await AddTask4MacListAsync(machine.IdxMacchinaSlave, updDict);
await MachineParamUpsertAsync(machine.IdxMacchinaSlave, list2upd);
}
}
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in forceSplitOdl{Environment.NewLine}{exc}");
}
}
return answ;
}
public string CalcRecipe(RecipeModel currRecipe)
{
return mongoController.CalcRecipe(currRecipe);
@@ -1379,6 +1745,31 @@ namespace MP.IOC.Data
return val != null && (val == "1" || val.ToLower() == "true");
}
/// <summary>
/// Restituisce il valore booleano se la macchina sia master
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
public async Task<bool> IobIsMasterAsync(string idxMacchina)
{
var key = Utils.RedKeyDatiMacc(idxMacchina, MpIoNS);
// 1. Tentativo ottimizzato: leggiamo solo il campo che ci serve
// Supponendo che tu usi StackExchange.Redis direttamente o un wrapper
string? val = await redisDb.HashGetAsync(key, "Master");
// 2. Se non c'è in cache, carichiamo/resettiamo tutto
if (val == null)
{
//var data = ResetDatiMacchina(idxMacchina);
var data = await ResetDatiMacchinaAsync(idxMacchina);
data.TryGetValue("Master", out val);
}
// 3. Parsing sicuro
return val != null && (val == "1" || val.ToLower() == "true");
}
/// <summary>
/// </summary>
/// <param name="IdxOdl">idxMacc odl da cercare</param>
@@ -2042,10 +2433,24 @@ namespace MP.IOC.Data
}
catch (Exception exc)
{
Log.Info(string.Format("Errore in mTaskMacchina | idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina));
Log.Error(string.Format("Errore in mTaskMacchina | idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina));
}
return answ;
}
/// <summary>
/// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
public async Task<Dictionary<string, string>> mTaskMacchinaAsync(string idxMacchina)
{
// hard coded dimensione vettore DatiMacchine
Dictionary<string, string> answ = new Dictionary<string, string>();
// ORA recupero da memoria redis...
var currHash = Utils.RedKeyTask2ExeMacc(idxMacchina, MpIoNS);
answ = await RedisGetHashDictAsync(currHash);
return answ;
}
/// <summary>
/// Generazione autoOdl
@@ -4650,6 +5055,32 @@ namespace MP.IOC.Data
return answ;
}
/// <summary>
/// Scrive una riga di evento manuale (barcode) nel db + check cambio stato DiarioDiBordo
/// </summary>
/// <param name="newRec">codice macchina</param>
/// <returns></returns>
private async Task<inputComandoMapo> scriviRigaEventoBarcodeAsync(EventListModel newRec)
{
bool inserito = false;
try
{
// inserisco evento
inserito = await IocDbController.EvListInsertAsync(newRec);
// faccio controllo per eventuale cambio stato da tab transizioni...
checkCambiaStatoBatch(tipoInputEvento.barcode, newRec.IdxMacchina, newRec.InizioStato ?? DateTime.Now, newRec.IdxTipo, newRec.CodArticolo, newRec.Value, newRec.MatrOpr, newRec.pallet);
}
catch (Exception exc)
{
Log.Error($"Errore in scriviRigaEvento | IdxMacchina {newRec.IdxMacchina} | IdxTipo {newRec.IdxTipo} | codArticolo {newRec.CodArticolo} | Value {newRec.Value} | MatrOpr {newRec.MatrOpr} | Pallet {newRec.pallet} | dTime {newRec.InizioStato}{Environment.NewLine}{exc}");
}
// formatto output
inputComandoMapo answ = new inputComandoMapo();
answ.outValue = inserito.ToString();
answ.needStatusRefresh = true;
return answ;
}
/// <summary>
/// Restituisce il valore booleano se la macchina sia abilitata all'inserimento COMPLETO nel
/// Signal Log
@@ -4751,7 +5182,6 @@ namespace MP.IOC.Data
{
answ = currRec.Valore;
}
return answ;
}
+1 -1
View File
@@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Version>6.16.2604.1618</Version>
<Version>6.16.2604.1708</Version>
</PropertyGroup>
<ItemGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MP-IOC </i>
<h4>Versione: 6.16.2604.1618</h4>
<h4>Versione: 6.16.2604.1708</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.16.2604.1618
6.16.2604.1708
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2604.1618</version>
<version>6.16.2604.1708</version>
<url>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>