Files
egwmultienginescript/BeamRESTPipe.lua
T
Emmanuele Sassi d76c2e37e6 - aggiunto RUID su tutte le richieste
- introdotta funzione EgtSanitizeUtf8 da LuaLibs
- aggiunta modalita' Balance su chiamata REST per Beam
- aggiunta funzione CreateBWEFromMachGroup
- aggiunta funzione per nesting travi
-  aggiunto calcolo lista soglie per finestre
- copiato file WindowRESTPipe da BeamRESTPipe
2026-01-09 13:32:19 +01:00

831 lines
37 KiB
Lua

--
-- EEEEEEEEEE GGGGGG TTTTTTTTTTTTTT
-- EEEEEEEEEE GGGGGGGGGG TTTTTTTTTTTTTT
-- EEEE GGGG GGGG TTTT
-- EEEE GGGG TTTT
-- EEEEEEE GGGG GGGGGGG TTTT
-- EEEEEEE GGGG GGGGGGG TTTT
-- EEEE GGGG GGGG TTTT
-- EEEE GGGG GGGG TTTT
-- EEEEEEEEEE GGGGGGGGGG TTTT
-- EEEEEEEEEE GGGGGG TTTT
--
-- BeamRESTPipe by Egalware s.r.l. 2025/12/02
-- Questo script gestisce le richieste REST che arrivano da LUX per le travi
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- modalita' di chiamata
QUESTION_MODES = {
NULL = 0,
PREVIEW = 1,
BOM = 2,
HARDWARE = 3,
CONFIG = 4,
ORDER = 5,
VERIFY = 6,
}
QUESTION_ORDER_SUBMODES = {
NULL = 0,
CREATE = 1,
ESTIMATE = 2,
BALANCE = 3,
}
PART_VERIFICATION_RESULTS = {
CALCULATIONFAILED = -1,
NOTMACHINABLE = 0,
MACHINABLE = 1,
}
_G.package.loaded.JSON = nil
local JSON = require( 'JSON')
local sIniFilePath = EgtGetIniFile()
local sScriptDir = EgtGetStringFromIni( 'Lux', 'ScriptDir', '', sIniFilePath)
EgtAddToPackagePath( sScriptDir .. '\\?.lua')
local sBaseDir = EgtGetStringFromIni( 'Beam', 'BaseDir', '', sIniFilePath)
EgtAddToPackagePath( sBaseDir .. '\\?.lua')
_G.package.loaded.BeamWallPipeLib = nil
local BeamWallPipeLib = require( 'BeamWallPipeLib')
-- Connessiona a Redis
local bRedisConnect, nRedisConnectionId = EgtRedisAsyncConnect( ENG.Param2)
if bRedisConnect then
EgtOutLog('Connessione con il server Redis dal Lua effettuata con successo con Id=' .. nRedisConnectionId .. '!')
else
nRedisConnectionId = 0
EgtOutLog('Errore! Impossibile connettersi con il server Redis dal Lua!')
end
local function Create_Order( QuestionArgs)
-- leggo argomenti passati
local sFile = QuestionArgs["FileName"]
local sBtl = QuestionArgs["SerializedData"]
local sOrderUID = QuestionArgs["OrderUID"]
local sUID = QuestionArgs["UID"]
local sTagList = QuestionArgs["TagList"]
if sFile and #sFile > 0 then
if sBtl and #sBtl > 0 then
if sOrderUID and #sOrderUID > 0 then
if sUID and #sUID > 0 then
if sTagList and #sTagList > 0 then
-- scrivo testo su file
local sDataDir = EgtGetStringFromIni( 'Lux', 'DataDir', '', sIniFilePath)
-- creo cartella ordine
local sBtlFilePath = sDataDir .. '\\Beam\\' .. sOrderUID
if not EgtExistsDirectory( sBtlFilePath) then
if not EgtCreateDirectory( sBtlFilePath) then
local sErrorMsg = 'Errore! Impossibile creare cartella ' .. sBtlFilePath .. ' per il progetto ' .. sOrderUID .. '!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
end
-- creo cartella riga d'ordine
sBtlFilePath = sDataDir .. '\\Beam\\' .. sOrderUID .. '\\' .. sUID
if EgtExistsDirectory( sBtlFilePath) then
if not EgtEmptyDirectory( sBtlFilePath) then
local sErrorMsg = 'Errore! Impossibile svuotare cartella ' .. sBtlFilePath .. ' per il progetto ' .. sOrderUID .. '!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
else
if not EgtCreateDirectory( sBtlFilePath) then
local sErrorMsg = 'Errore! Impossibile creare cartella ' .. sBtlFilePath .. ' per il progetto ' .. sOrderUID .. '!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
end
_, _, sExt = EgtSplitPath( sFile)
sBtlFilePath = sBtlFilePath .. '\\' .. sUID .. sExt
-- Apro file Input in scrittura
local fhBtl = io.open( sBtlFilePath, 'w')
if not fhBtl then
local sErrorMsg = 'Errore! Apertura file ' .. sBtlFilePath .. ' per scrittura btl non riuscita!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
-- Scrittura nuova linea
fhBtl:write( sBtl .. '\n')
-- Chiudo file
fhBtl:close()
-- verifico tipo di file
local bOk = false
if string.lower( sExt) == '.btl' then
bOk = EgtImportBtl( sBtlFilePath)
elseif string.lower( sExt) == '.btlx' then
bOk = EgtImportBtlx( sBtlFilePath)
else
local sErrorMsg = 'Errore! Estensione file non riconosciuta!'
EgtOutLog(sErrorMsg)
os.remove(sBtlFilePath)
return 0, { Error = sErrorMsg}
end
if not bOk then
local sErrorMsg = 'Errore! Importazione file non riuscita!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
-- assegno etichette ai pezzi
local TagList = EgtSplitString( sTagList, ',')
local nPartId = EgtGetFirstPart()
local nTagIndex = 1
while nPartId do
local nCnt = EgtGetInfo( nPartId, "CNT", 'i')
local sPartTagList = ''
for nCntIndex = 1, nCnt do
sPartTagList = sPartTagList .. TagList[nTagIndex] .. EgtIf( nCntIndex < nCnt, ',', '')
nTagIndex = nTagIndex + 1
end
EgtSetInfo( nPartId, 'LuxTagList', sPartTagList)
nPartId = EgtGetNextPart( nPartId)
end
local sNgeFilePath = sDataDir .. '\\Beam\\' .. sOrderUID .. '\\' .. sUID .. '\\' .. sUID .. '.nge'
EgtSaveFile( sNgeFilePath, GDB_NT.CMPTXT)
-- do risultato
return 1, {}
else
local sErrorMsg = 'Errore! Lista etichette vuota!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
else
local sErrorMsg = 'Errore! UID vuoto!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
else
local sErrorMsg = 'Errore! Nome ordine vuoto!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
else
local sErrorMsg = 'Errore! Btl file vuoto!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
else
local sErrorMsg = 'Errore! Nome file vuoto!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
end
local function Calc_Estimate( QuestionArgs)
-- leggo argomenti passati
local sOrderUID = QuestionArgs["OrderUID"]
local sUID = QuestionArgs["UID"]
if sOrderUID and #sOrderUID > 0 then
if sUID and #sUID > 0 then
-- apro progetto
local sDataDir = EgtGetStringFromIni( 'Lux', 'DataDir', '', sIniFilePath)
local sOrderDirPath = sDataDir .. '\\Beam\\' .. sOrderUID .. '\\' .. sUID
if not EgtExistsDirectory( sOrderDirPath) then
local sErrorMsg = 'Errore! Cartella della riga d\'ordine non trovata!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
local sNgeFilePath = sOrderDirPath .. '\\' .. sUID .. '.nge'
if not EgtOpenFile( sNgeFilePath) then
local sErrorMsg = 'Errore! Fallita apertura del file!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
-- recupero cartella macchine
local MachineDirPath = EgtGetStringFromIni( 'Mach', 'MachinesDir', '', sIniFilePath)
if not MachineDirPath or #MachineDirPath <=0 then
local sErrorMsg = 'Errore! Cartella delle macchine non impostata!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
--local MachinesDir = EgtFindAllFiles( MachineDirPath .. '\\*.*')
--local MachinesDir = { MachineDirPath .. '\\Saomad-Kairos', MachineDirPath .. '\\Essetre-FAST', MachineDirPath .. '\\Essetre-PF1250MAX' }
local MachinesDir = { MachineDirPath .. '\\Saomad-Kairos', MachineDirPath .. '\\Essetre-FAST'}
--local MachinesDir = { MachineDirPath .. '\\Essetre-FAST'}
local BeamMachineList = {}
local AnswerChannelList = {}
for nMachineIndex = 1, #MachinesDir do
local _, sMachineName, _ = EgtSplitPath( MachinesDir[nMachineIndex])
local sMaterial = EgtGetStringFromIni( 'General', 'Material', '', MachineDirPath .. '\\' .. sMachineName .. '\\' .. sMachineName .. '.ini')
if sMaterial == 'Beam' then
local sMachineOrderDirPath = sOrderDirPath .. '\\' .. sMachineName
-- creo cartella per macchina
if EgtExistsDirectory( sMachineOrderDirPath) then
if not EgtEmptyDirectory( sMachineOrderDirPath) then
local sErrorMsg = 'Errore! Impossibile svuotare cartella ' .. sMachineOrderDirPath .. ' per il progetto ' .. sOrderUID .. '!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
else
if not EgtCreateDirectory( sMachineOrderDirPath) then
local sErrorMsg = 'Errore! Impossibile creare cartella ' .. sMachineOrderDirPath .. ' per il progetto ' .. sOrderUID .. '!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
end
local sMachineNgeFilePath = sMachineOrderDirPath .. '\\' .. sUID .. '.nge'
-- e copio file nge
if not EgtCopyFile( sNgeFilePath, sMachineNgeFilePath) then
local sErrorMsg = 'Errore! Copia del file nge per macchina ' .. sMachineName .. ' e progetto ' .. sUID .. ' fallita!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
if not EgtOpenFile( sMachineNgeFilePath) then
local sErrorMsg = 'Errore! Fallita apertura del file per macchina ' .. sMachineName .. '!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
-- creo i singoli bwe e li mando da eseguire via redis
local nPartId = EgtGetFirstPart()
local AnswerArgs = {}
local TagTimeList = {}
local dTotTime = 0
local nNotMachinedPart = 0
while nPartId do
local BarPath = sMachineOrderDirPath
local ProjType = BWTYPES.BEAM
local GlobState = CALCSTATES.NOTCALCULATED
local bResult, AnswerChannel = BeamWallPipeLib.AsyncVerifyPartCalc( nPartId, BarPath, ProjType, sMachineName, GlobState)
if bResult then
table.insert( AnswerChannelList, { Channel = AnswerChannel, PartId = nPartId, Machine = sMachineName})
else
local sErrorMsg = 'Errore! Tentativo di verifica del pezzo ' .. nPartId .. ' fallito!'
EgtOutLog(sErrorMsg)
end
nPartId = EgtGetNextPart( nPartId)
end
table.insert( BeamMachineList, { Name = sMachineName, PartList = { }})
end
end
local nTimeCount = 0
local nTimeClock = 100
while nTimeCount < 1200 and #AnswerChannelList > 0 do
local RemoveAnswerList = {}
for nAnswerIndex = 1, #AnswerChannelList do
local AnswerChannel = AnswerChannelList[nAnswerIndex]
-- verifico se ci sono i risultati e aspetto che arrivino tutti
local bOk, bAnswerReceived, PartAnswerArgs = BeamWallPipeLib.AsyncVerifyPartResult( AnswerChannel.Channel)
if bOk then
if bAnswerReceived then
if PartAnswerArgs then
local sTagList = EgtGetInfo( AnswerChannel.PartId, 'LuxTagList')
local TagList = EgtSplitString( sTagList, ',')
local CalcResult
CalcResult = EgtIf( tonumber( PartAnswerArgs.MachiningOk) == 1, PART_VERIFICATION_RESULTS.MACHINABLE, PART_VERIFICATION_RESULTS.NOTMACHINABLE)
local BeamMachine = ''
for nMachineIndex = 1, #BeamMachineList do
if BeamMachineList[nMachineIndex].Name == AnswerChannel.Machine then
BeamMachine = BeamMachineList[nMachineIndex]
end
end
for nTagIndex = 1, #TagList do
table.insert( BeamMachine.PartList, { Tag = TagList[nTagIndex], CalcResult = CalcResult, Time = ( PartAnswerArgs.Time or 0)})
end
table.insert( RemoveAnswerList, nAnswerIndex)
else
local sErrorMsg = 'Errore! Tentativo di verifica del pezzo sul canale' .. AnswerChannel.Channel .. ' fallito!'
EgtOutLog(sErrorMsg)
end
end
elseif bOk then
local sErrorMsg = 'Errore! Funzione di lettura risultato sul canale ' .. AnswerChannel.Channel .. ' fallita!'
EgtOutLog(sErrorMsg)
end
end
for nRemoveAnswerCount = #RemoveAnswerList, 1, -1 do
table.remove( AnswerChannelList, RemoveAnswerList[nRemoveAnswerCount])
end
EgtPause( nTimeClock, true)
nTimeCount = nTimeCount + 1
end
if #AnswerChannelList > 0 then
for nAnswerCount = 1, #AnswerChannelList do
local sTagList = EgtGetInfo( AnswerChannelList[nAnswerCount].PartId, 'LuxTagList')
local TagList = EgtSplitString( sTagList, ',')
CalcResult = PART_VERIFICATION_RESULTS.CALCULATIONFAILED
local sErrorMsg = 'Errore! Verifica sul pezzo ' .. AnswerChannelList[nAnswerCount].PartId .. ' fallita!'
EgtOutLog(sErrorMsg)
local BeamMachine
for nMachineIndex = 1, #BeamMachineList do
if BeamMachineList[nMachineIndex].Name == AnswerChannelList[nAnswerCount].Machine then
BeamMachine = BeamMachineList[nMachineIndex]
end
end
for nTagIndex = 1, #TagList do
table.insert( BeamMachine.PartList, { Tag = TagList[nTagIndex], CalcResult = CalcResult, Time = 0})
end
end
end
-- do risultato
local JsonBeamMachineList = JSON:encode( BeamMachineList)
return 1, { Estimate = JsonBeamMachineList}
else
local sErrorMsg = 'Errore! UID vuoto!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
else
local sErrorMsg = 'Errore! OrderUID vuoto!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
end
local function IsTagInPart( nPartId, TagList)
local sPartTagList = EgtGetInfo( nPartId, 'LuxTagList')
local PartTagList = EgtSplitString( sPartTagList, ',')
local nQuantity = 0
for nPartTagListIndex = 1, #PartTagList do
for nTagListIndex = 1, #TagList do
if PartTagList[nPartTagListIndex] == TagList[nTagListIndex] then
nQuantity = nQuantity + 1
end
end
end
return nQuantity > 0, nQuantity
end
-- Calcola la deviazione rispetto alle percentuali desiderate
local function computeDeviation(machineLoads, percentages)
local total = 0
for _, load in ipairs(machineLoads) do
total = total + load
end
if total == 0 then
return 0
end
local dev = 0
for j, load in ipairs(machineLoads) do
local q = load / total
local p = percentages[j]
dev = dev + (q - p) * (q - p)
end
return dev
end
-- Algoritmo greedy per assegnare i pezzi alle macchine
local function assignGreedy(items, percentages)
local N = #items
local M = #items[1].MachGroupList
-- carico iniziale per macchina
local machineLoads = {}
for j = 1, M do
machineLoads[j] = 0
end
-- assegnazione: per ogni pezzo, indice della macchina scelta (1..M)
local assignment = {}
-- ORDINAMENTO INTELLIGENTE:
-- 1) prima i pezzi con meno macchine valide
-- 2) a parità, quelli più pesanti
table.sort(items, function(a, b)
local validA, validB = 0, 0
for _, m in ipairs(a.MachGroupList) do
if m.CalcResult and m.CalcResult > 0 then
validA = validA + 1
end
end
for _, m in ipairs(b.MachGroupList) do
if m.CalcResult and m.CalcResult > 0 then
validB = validB + 1
end
end
if validA ~= validB then
return validA < validB
end
local maxA, maxB = 0, 0
for _, m in ipairs(a.MachGroupList) do
if m.Time > maxA then
maxA = m.Time
end
end
for _, m in ipairs(b.MachGroupList) do
if m.Time > maxB then
maxB = m.Time
end
end
return maxA > maxB
end)
for i, item in ipairs(items) do
local bestMachine = nil
local bestDev = nil
-- prova ad assegnare il pezzo a ciascuna macchina
for j = 1, M do local mInfo = item.MachGroupList[j]
-- VINCOLO: CalcResult deve essere > 0
if mInfo.CalcResult and mInfo.CalcResult > 0 then
local time = mInfo.Time
-- prova temporaneamente
machineLoads[j] = machineLoads[j] + time
local dev = computeDeviation(machineLoads, percentages)
machineLoads[j] = machineLoads[j] - time
if bestDev == nil or dev < bestDev then
bestDev = dev bestMachine = j
end
end
end
--for j = 1, M do
-- local time = item.MachGroupList[j].Time
--
-- -- aggiorna temporaneamente il carico
-- machineLoads[j] = machineLoads[j] + time
-- local dev = computeDeviation(machineLoads, percentages)
-- machineLoads[j] = machineLoads[j] - time -- rollback
--
-- if bestDev == nil or dev < bestDev then
-- bestDev = dev
-- bestMachine = j
-- end
--end
-- Se nessuna macchina è valida → errore
-- DA MIGLIORARE! se nessuna macchina riesce a farlo, devo rivalutare i pezzi singoli su ogni macchina e farne la somma
if not bestMachine then
local sErrorMsg = 'Errore! Nessuna macchina valida per il MachGroup ' .. tostring(item.Index) .. '!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
-- assegna definitivamente
assignment[i] = bestMachine
local chosenTime = item.MachGroupList[bestMachine].Time
machineLoads[bestMachine] = machineLoads[bestMachine] + chosenTime
end
return assignment, machineLoads
end
local function Calc_Balance( QuestionArgs)
-- leggo argomenti passati
local sOrderUID = QuestionArgs["OrderUID"]
local sUID = QuestionArgs["UID"]
local dBarLenght = tonumber( QuestionArgs["BarLenght"])
local sTagList = QuestionArgs["TagList"]
if sOrderUID and #sOrderUID > 0 then
if sUID and #sUID > 0 then
-- recupero cartella progetto
local sDataDir = EgtGetStringFromIni( 'Lux', 'DataDir', '', sIniFilePath)
local sOrderDirPath = sDataDir .. '\\Beam\\' .. sOrderUID .. '\\' .. sUID
if not EgtExistsDirectory( sOrderDirPath) then
local sErrorMsg = 'Errore! Cartella della riga d\'ordine non trovata!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
-- verifico esistenza cartella per progetti di bilanciamento
local sBalanceDirPath = sOrderDirPath .. '\\Balance'
if EgtExistsDirectory( sBalanceDirPath) then
if not EgtEmptyDirectory( sBalanceDirPath) then
local sErrorMsg = 'Errore! Impossibile svuotare cartella ' .. sBalanceDirPath .. ' per il progetto ' .. sOrderUID .. '!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
else
if not EgtCreateDirectory( sBalanceDirPath) then
local sErrorMsg = 'Errore! Impossibile creare cartella ' .. sBalanceDirPath .. ' per il progetto ' .. sOrderUID .. '!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
end
-- creo cartella per progetto di bilanciamento corrente
local nCurrTime = os.time()
local sCurrBalanceDirPath = sBalanceDirPath .. '\\' .. nCurrTime
if not EgtCreateDirectory( sCurrBalanceDirPath) then
local sErrorMsg = 'Errore! Impossibile creare cartella ' .. sCurrBalanceDirPath .. ' per il progetto ' .. sOrderUID .. '!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
local sNgeFilePath = sOrderDirPath .. '\\' .. sUID .. '.nge'
local sBalanceNgeFilePath = sCurrBalanceDirPath .. '\\' .. sUID .. '_' .. nCurrTime .. '.nge'
if not EgtCopyFile( sNgeFilePath, sBalanceNgeFilePath) then
local sErrorMsg = 'Errore! Fallita copia del file!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
if not EgtOpenFile( sBalanceNgeFilePath) then
local sErrorMsg = 'Errore! Fallita apertura del file!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
-- recupero Id dei pezzi da nestare
local TagList = EgtSplitString( sTagList)
local nPartId = EgtGetFirstPart()
local PartIdList = {}
local nPartCount = 0
while nPartId do
local bFound, nQuantity = IsTagInPart( nPartId, TagList)
if bFound then
PartIdList[nPartId] = nQuantity
nPartCount = nPartCount + nQuantity
end
nPartId = EgtGetNextPart( nPartId)
end
local RawList = { { Len = dBarLenght, Qty = nPartCount}}
-- recupero cartella macchine
local MachineDirPath = EgtGetStringFromIni( 'Mach', 'MachinesDir', '', sIniFilePath)
if not MachineDirPath or #MachineDirPath <=0 then
local sErrorMsg = 'Errore! Cartella delle macchine non impostata!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
--local MachinesDir = EgtFindAllFiles( MachineDirPath .. '\\*.*')
--local MachinesDir = { MachineDirPath .. '\\Saomad-Kairos', MachineDirPath .. '\\Essetre-FAST', MachineDirPath .. '\\Essetre-PF1250MAX' }
local MachinesDir = { MachineDirPath .. '\\Saomad-Kairos', MachineDirPath .. '\\Essetre-FAST'}
--local MachinesDir = { MachineDirPath .. '\\Essetre-FAST'}
local sReqBalance = QuestionArgs["ReqBalance"]
local ReqBalance = JSON:decode( sReqBalance)
local MachineNameList = {}
local PercentageList = {}
for sMachineName, dPercentage in pairs(ReqBalance) do
if EgtExistsDirectory( MachineDirPath .. '\\' .. sMachineName) then
table.insert( MachineNameList, sMachineName)
table.insert( PercentageList, dPercentage)
end
end
local StartOffset = 20
local Offset = 6
-- faccio nesting dei pezzi
local sNestingLogFilePath = sOrderDirPath .. '\\' .. sUID .. '_' .. nCurrTime .. 'NestLog.txt'
local bOk, sErrorMsg = BeamWallPipeLib.NestBeam( PartIdList, RawList, MachineNameList, StartOffset, Offset, sNestingLogFilePath)
if not bOk then
return 0, { Error = sErrorMsg}
end
EgtSaveFile()
-- eseguo verifica dei gruppi di lavorazione creati
-- creo i singoli bwe e li mando da eseguire via redis
local AnswerChannelList = {}
local nMachGroupId = EgtGetFirstMachGroup()
local AnswerArgs = {}
local TagTimeList = {}
local dTotTime = 0
local nNotMachinedPart = 0
local MachGroupList = {}
local NestList = {}
while nMachGroupId do
local BarPath = sCurrBalanceDirPath
local ProjType = BWTYPES.BEAM
local sMachineName = EgtGetMachGroupMachineName( nMachGroupId)
local GlobState = CALCSTATES.NOTCALCULATED
local bResult, AnswerChannel = BeamWallPipeLib.AsyncVerifyPartCalc( nMachGroupId, BarPath, ProjType, sMachineName, GlobState, true)
if bResult then
table.insert( AnswerChannelList, { Channel = AnswerChannel, PartId = nMachGroupId, Machine = sMachineName})
else
local sErrorMsg = 'Errore! Tentativo di verifica della barra ' .. nMachGroupId .. ' fallito!'
EgtOutLog(sErrorMsg)
end
local nNestIndex = EgtGetInfo( nMachGroupId, "NestIndex", 'i')
local bFound = false
for nMachGroupIndex = 1, #NestList do
local CurrNest = NestList[nMachGroupIndex]
if nNestIndex == CurrNest.NestIndex then
bFound = true
table.insert( CurrNest.MachGroupList, { PartId = nMachGroupId, Machine = sMachineName})
end
end
if not bFound then
table.insert( NestList, { NestIndex = nNestIndex, MachGroupList = { { PartId = nMachGroupId, Machine = sMachineName}}})
end
table.insert( MachGroupList, { PartId = nMachGroupId, NestIndex = nNestIndex, Machine = sMachineName})
nMachGroupId = EgtGetNextMachGroup( nMachGroupId)
end
local nTimeCount = 0
local nTimeClock = 100
while nTimeCount < 1200 and #AnswerChannelList > 0 do
local RemoveAnswerList = {}
for nAnswerIndex = 1, #AnswerChannelList do
local AnswerChannel = AnswerChannelList[nAnswerIndex]
-- verifico se ci sono i risultati e aspetto che arrivino tutti
local bOk, bAnswerReceived, PartAnswerArgs = BeamWallPipeLib.AsyncVerifyPartResult( AnswerChannel.Channel)
if bOk then
if bAnswerReceived then
if PartAnswerArgs then
if PartAnswerArgs.Error then
local sErrorMsg = 'Errore! La verifica del pezzo ' .. AnswerChannel.PartId .. ' ha restituito un errore! (' .. PartAnswerArgs.Error .. ')'
EgtOutLog(sErrorMsg)
else
--local sTagList = EgtGetInfo( AnswerChannel.PartId, 'LuxTagList')
--local TagList = EgtSplitString( sTagList, ',')
--
local CalcResult
CalcResult = EgtIf( tonumber( PartAnswerArgs.MachiningOk) == 1, PART_VERIFICATION_RESULTS.MACHINABLE, PART_VERIFICATION_RESULTS.NOTMACHINABLE)
for nMachGroupIndex = 1, #MachGroupList do
local CurrMachGroup = MachGroupList[nMachGroupIndex]
if CurrMachGroup.PartId == tonumber( PartAnswerArgs.BarId) then
CurrMachGroup.CalcResult = CalcResult
CurrMachGroup.Time = ( tonumber( PartAnswerArgs.Time) or 0)
end
end
local bNestFound = false
for nNestIndex = 1, #NestList do
if not bNestFound then
for nMachGroupIndex = 1, #NestList[nNestIndex].MachGroupList do
local CurrMachGroup = NestList[nNestIndex].MachGroupList[nMachGroupIndex]
if CurrMachGroup.PartId == tonumber( PartAnswerArgs.BarId) then
CurrMachGroup.CalcResult = CalcResult
CurrMachGroup.Time = ( tonumber( PartAnswerArgs.Time) or 0)
bNestFound = true
break
end
end
end
end
end
table.insert( RemoveAnswerList, nAnswerIndex)
else
local sErrorMsg = 'Errore! Tentativo di verifica del pezzo sul canale' .. AnswerChannel.Channel .. ' fallito!'
EgtOutLog(sErrorMsg)
end
end
elseif bOk then
local sErrorMsg = 'Errore! Funzione di lettura risultato sul canale ' .. AnswerChannel.Channel .. ' fallita!'
EgtOutLog(sErrorMsg)
end
end
for nRemoveAnswerCount = #RemoveAnswerList, 1, -1 do
table.remove( AnswerChannelList, RemoveAnswerList[nRemoveAnswerCount])
end
EgtPause( nTimeClock, true)
nTimeCount = nTimeCount + 1
end
if #AnswerChannelList > 0 then
for nAnswerCount = 1, #AnswerChannelList do
local sTagList = EgtGetInfo( AnswerChannelList[nAnswerCount].PartId, 'LuxTagList')
local TagList = EgtSplitString( sTagList, ',')
CalcResult = PART_VERIFICATION_RESULTS.CALCULATIONFAILED
local sErrorMsg = 'Errore! Verifica sul pezzo ' .. AnswerChannelList[nAnswerCount].PartId .. ' fallita!'
EgtOutLog(sErrorMsg)
for nMachGroupIndex = 1, #MachGroupList do
local CurrMachGroup = MachGroupList[nMachGroupIndex]
if CurrMachGroup.PartId == AnswerChannelList.PartId then
CurrMachGroup.CalcResult = 0
CurrMachGroup.Time = 0
end
end
local bNestFound = false
for nNestIndex = 1, #NestList do
if not bNestFound then
for nMachGroupIndex = 1, #NestList[nNestIndex].MachGroupList do
local CurrMachGroup = NestList[nNestIndex].MachGroupList[nMachGroupIndex]
if CurrMachGroup.PartId == AnswerChannelList.PartId then
CurrMachGroup.CalcResult = 0
CurrMachGroup.Time = 0
bNestFound = true
break
end
end
end
end
end
end
-- divido le barre sulle macchine secondo le percentuali dei tempi
local assignment, loads = assignGreedy(NestList, PercentageList)
local MachineTagList = { }
for nAssignmentIndex = 1, #assignment do
local nMachGroupId = NestList[nAssignmentIndex].MachGroupList[assignment[nAssignmentIndex]].PartId
local sMachineName = NestList[nAssignmentIndex].MachGroupList[assignment[nAssignmentIndex]].Machine
EgtSetCurrMachGroup( nMachGroupId)
local nRawPartId = EgtGetFirstRawPart()
while nRawPartId do
local nPartId = EgtGetFirstPartInRawPart( nRawPartId)
while nPartId do
local sTag = EgtGetInfo( nPartId, 'LuxTag')
if not MachineTagList[sMachineName] then
MachineTagList[sMachineName] = { }
MachineTagList[sMachineName].TagList = { }
MachineTagList[sMachineName].BarQty = 0
MachineTagList[sMachineName].Time = 0
end
table.insert( MachineTagList[sMachineName].TagList, sTag)
nPartId = EgtGetNextPartInRawPart( nRawPartId)
end
nRawPartId = EgtGetNextRawPart( nRawPartId)
end
MachineTagList[sMachineName].BarQty = MachineTagList[sMachineName].BarQty + 1
MachineTagList[sMachineName].Time = MachineTagList[sMachineName].Time + NestList[nAssignmentIndex].MachGroupList[assignment[nAssignmentIndex]].Time
end
EgtResetCurrMachGroup()
-- do risultato
local JsonMachineTagList = JSON:encode( MachineTagList)
return 1, { Balance = JsonMachineTagList}
else
local sErrorMsg = 'Errore! UID vuoto!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
else
local sErrorMsg = 'Errore! OrderUID vuoto!'
EgtOutLog(sErrorMsg)
return 0, { Error = sErrorMsg}
end
end
local nErr = 999
local nNilCount = 0
local bRun = true
while bRun do
local sReadLine = io.stdin:read( 'l')
EgtOutLog( 'Letta riga da stdin')
if sReadLine then
if sReadLine == 'quit' then
EgtOutLog( 'Chiusura processo')
break
end
if sReadLine ~= '' and sReadLine:find( '^#8477271#') and sReadLine:find( '#8477271#$') then
EgtOutLog( 'Lettura istruzione valida')
sReadLine = string.sub( sReadLine, 10, #sReadLine - 9)
local sSanitizedReadLine = EgtSanitizeUtf8( sReadLine)
local Question = JSON:decode( sSanitizedReadLine)
local nThreadIndex = -1
local nId = -1
local ExecEnvironment = -1
local nResult = 0
local AnswerArgs = {}
if Question and Question.nThreadIndex and Question.nId and Question.Args then
nThreadIndex = tonumber( Question["nThreadIndex"])
nId = tonumber( Question["nId"])
ExecEnvironment = tonumber( Question["ExecEnvironment"])
local QuestionArgs = Question["Args"]
if QuestionArgs and QuestionArgs.Mode and QuestionArgs.UID then
local sUid = QuestionArgs["UID"]
local sRUID = QuestionArgs["RUID"]
local nMode = tonumber( QuestionArgs["Mode"])
-- esecuzione della corretta modilita'
EgtOutLog('Ricevuta richiesta calcolo: nThreadIndex=' .. nThreadIndex .. ', nId=' .. nId .. ', UID=' .. sUid .. ', nMode=' .. nMode)
local Result = {}
if nMode == QUESTION_MODES.ORDER then
if QuestionArgs.SubMode then
local nSubMode = tonumber( QuestionArgs["SubMode"])
EgtOutLog('SubMode=' .. nSubMode)
if nSubMode == QUESTION_ORDER_SUBMODES.CREATE then
nResult, AnswerArgs = Create_Order( QuestionArgs)
elseif nSubMode == QUESTION_ORDER_SUBMODES.ESTIMATE then
_G.LUX = {}
LUX.REDISID = nRedisConnectionId
nResult, AnswerArgs = Calc_Estimate( QuestionArgs)
elseif nSubMode == QUESTION_ORDER_SUBMODES.BALANCE then
_G.LUX = {}
LUX.REDISID = nRedisConnectionId
nResult, AnswerArgs = Calc_Balance( QuestionArgs)
else
nResult = 0
local sErrorMsg = 'Errore! Valore di SubMode errato!'
AnswerArgs = { Error = sErrorMsg}
EgtOutLog( sErrorMsg)
end
if AnswerArgs then
AnswerArgs.Mode = nMode
AnswerArgs.SubMode = nSubMode
end
else
nResult = 0
local sErrorMsg = 'Errore! Domanda senza SubMode che é obbligatorio!'
AnswerArgs = { Error = sErrorMsg}
EgtOutLog( sErrorMsg)
end
end
AnswerArgs.UID = sUid
AnswerArgs.RUID = sRUID or 0
else
nResult = 0
local sErrorMsg = 'Errore! Domanda senza argomenti o senza UID o Mode che sono obbligatori!'
AnswerArgs = { Error = sErrorMsg}
EgtOutLog( sErrorMsg)
end
else
nResult = 0
local sErrorMsg = 'Errore! Formato domanda non riconosciuto o senza nThreadIndex, nId o Args!'
AnswerArgs = { Error = sErrorMsg}
EgtOutLog( sErrorMsg)
end
-- do risultato
local Result = { nThreadIndex = nThreadIndex,
nId = nId,
ExecEnvironment = ExecEnvironment,
nResult = nResult,
Args = AnswerArgs}
-- invio risposta
EgtOutLog( 'Invio risposta')
local JsonResult = JSON:encode( Result)
io.stdout:write( "#8376261#" .. JsonResult .. "#8376261#" .. '\n')
io.stdout:flush()
EgtOutLog( 'Risposta inviata')
EgtNewFile()
end
else
if nNilCount >= 20 then
bRun = false
EgtOutLog( 'Errore! Lettura da stdin fallita!')
end
nNilCount = nNilCount + 1
EgtPause( 100, true)
end
end
EgtRedisAsyncDisconnect( nRedisConnectionId)