Stima di valori in un Task utilizzando i modelli di Machine Learning e la primitiva QWml.Prediction

' In questo esempio viene effettuata la stima di due valori di livello idrometrico utilizzando la primitiva QWml.Prediction e partendo da due differenti modelli di Machine Learning, 
' aventi codice "0002" e "0003". 
' La stima viene memorizzata nella tabella IOTLOG, e i valori delle variabili indipendenti vengono acquisiti sempre dalla tabella IOTLOG, e corrispondono alle ultime letture disponibili
' dei livelli in due punti a monte rispetto al punto per il quale si vuole calcolare la stima. Quest'ultima sarà riferita riferita a 4 ore avanti rispetto all'orario dell'ultima lettura 
' nel punto più a valle prima di quello per il quale si calcola la stima, supponendo che questo sia il periodo che l'acqua impiega a percorrere la distanza fra i due punti.

Dim Q as new QWTable
Q.Database=DB
Q.sql="select * from IOTLOG"
Q.allowallrecords=false
Q.active=true

Dim Q1 as new QWTable
Q1.Database=DB
Q1.sql="select "
Q1.sql+="i.DATA,"
Q1.sql+="convert(real,(select VALUE from IOTLOG i1 where i1.DATA=Dateadd(minute,-1*60,i.DATA) and i1.DEVICENAME='RENO' and i1.SENSORNAME = 'SASSO MARCONI')) as 'SASSO_MARCONI', "
Q1.sql+="convert(real,(select VALUE from IOTLOG i1 where i1.DATA=i.DATA and i1.DEVICENAME='RENO' and i1.SENSORNAME = 'CHIUSA CASALECCHIO')) as 'CHIUSA_CASALECCHIO' "
Q1.sql+="from IOTLOG i where DEVICENAME='RENO' and SENSORNAME='BONCONVENTO' and DATA>=dateadd(day,-2,getdate()) group by DATA order by DATA "
Q1.allowallrecords=false
Q1.active=true

while not q1.rowset.endofset
   ' Stima l'altezza 
   dim errmsg as string
   dim score as double
   dim values as new assocarray
   values("SASSO_MARCONI")=q1.rowset.fields("SASSO_MARCONI").value
   values("CHIUSA_CASALECCHIO")=q1.rowset.fields("CHIUSA_CASALECCHIO").value   

   if not empty(q1.rowset.fields("SASSO_MARCONI").value) and not empty(q1.rowset.fields("CHIUSA_CASALECCHIO").value)
      score=QWml.Prediction(DB.QWSession, "0002", Values, errmsg) ' Previsione
   
      if empty(errmsg)
         dim Data as datetime=dateadd(Dateinterval.minute,4*60,q1.rowset.fields("DATA").value) ' La data cui si riferisce la stima è 4 ore avanti quella della lettura a Casalecchio, che è approssimativamente il tempo impiegato dal flusso a percorrere il tragitto

         if not q.rowset.findkey(Data,"RENO","BONCONVENTO_P4H_0002")
             q.beginappend()
             q.replace("DATA",data)
             q.replace("DEVICENAME","RENO")
             q.replace("SENSORNAME","BONCONVENTO_P4H_0002")
             q.replace("VALUE",score)
            q.saverecord()
         End If
      else
         throw new exception("Errore durante la stima 0002: "+errmsg)
      End If
      
      score=QWml.Prediction(DB.QWSession, "0003", Values, errmsg) ' Previsione
   
      if empty(errmsg)
         dim Data as datetime=dateadd(Dateinterval.minute,4*60,q1.rowset.fields("DATA").value) ' La data cui si riferisce la stima è 4 ore avanti quella della lettura a Casalecchio, che è approssimativamente il tempo impiegato dal flusso a percorrere il tragitto

         if not q.rowset.findkey(Data,"RENO","BONCONVENTO_P4H_0003")
             q.beginappend()
             q.replace("DATA",data)
             q.replace("DEVICENAME","RENO")
             q.replace("SENSORNAME","BONCONVENTO_P4H_0003")
             q.replace("VALUE",score)
            q.saverecord()
         End If
      else
         throw new exception("Errore durante la stima: "+errmsg)
      End If
      
   End If 

   Q1.rowset.next()
End While

Q.active=false
Q1.active=false