/// <summary> /// Corpo del job /// </summary> protected override void DoJob() { // Acquisisco le connessioni presenti nel database DataTable connections = wet_db.ExecCustomQuery("SELECT * FROM connections"); connections.PrimaryKey = new DataColumn[] { connections.Columns["id_odbcdsn"] }; // Acquisisco le misure presenti nel database DataTable measures = wet_db.ExecCustomQuery("SELECT * FROM measures"); // Ciclo per tutte le misure foreach (DataRow measure in measures.Rows) { try { // Acquisisco l'ID univoco della misura int id_measure = Convert.ToInt32(measure["id_measures"]); int id_odbc_dsn = Convert.ToInt32(measure["connections_id_odbcdsn"]); MeasureTypes mtype = (MeasureTypes)Convert.ToInt32(measure["type"]); bool reliable = Convert.ToBoolean(measure["reliable"]); DateTime start_date = Convert.ToDateTime(measure["update_timestamp"]); double energy_specific_content = Convert.ToDouble(measure["energy_specific_content"]) * 3.6d; // KWh/mc -> KW/(l/s) // Popolo le coordinate database per la misura MeasureDBCoord_Struct measure_coord; int dsn_id = Convert.ToInt32(measure["connections_id_odbcdsn"]); measure_coord.odbc_connection = Convert.ToString(connections.Rows.Find(dsn_id)["odbc_dsn"]); measure_coord.username = (connections.Rows.Find(dsn_id)["username"] == DBNull.Value ? null : Convert.ToString(connections.Rows.Find(dsn_id)["username"])); measure_coord.password = (connections.Rows.Find(dsn_id)["password"] == DBNull.Value ? null : Convert.ToString(connections.Rows.Find(dsn_id)["password"])); measure_coord.table_name = Convert.ToString(measure["table_name"]); measure_coord.timestamp_column = Convert.ToString(measure["table_timestamp_column"]); measure_coord.value_column = Convert.ToString(measure["table_value_column"]); measure_coord.relational_id_column = Convert.ToString(measure["table_relational_id_column"]); measure_coord.relational_id_value = Convert.ToString(measure["table_relational_id_value"]); measure_coord.relational_id_type = (WetDBConn.PrimaryKeyColumnTypes)Convert.ToInt32(measure["table_relational_id_type"]); // Istanzio la connessione al database sorgente WetDBConn source_db = new WetDBConn(measure_coord.odbc_connection, measure_coord.username, measure_coord.password, false); // Estraggo il timestamp dell'ultimo valore scritto nel database sorgente DateTime last_source = GetLastSourceSample(source_db, start_date, measure_coord); // Estraggo il timestamp dell'ultimo valore scritto nel database WetNet DateTime last_dest = GetLastDestSample(id_measure); if (last_dest == DateTime.MinValue) last_dest = start_date; // Controllo se ci sono campioni da acquisire if (last_dest < last_source) { // Acquisisco tutti i campioni da scrivere DataTable samples = source_db.ExecCustomQuery(GetBaseQueryStr(source_db, measure_coord, last_dest, DateTime.Now, WetDBConn.OrderTypes.ASC, MAX_RECORDS_IN_QUERY)); // Gestione dei contatori volumetrici if (mtype == MeasureTypes.COUNTER) { // Acquisisco il campione precedente al primo della tabella samples DataTable cnt_tbl = source_db.ExecCustomQuery(GetBaseQueryStr(source_db, measure_coord, WetDBConn.START_DATE, last_dest.Subtract(new TimeSpan(0, 0, 0, 1)), WetDBConn.OrderTypes.DESC, 1)); // Lo inserisco nella tabella samples if (cnt_tbl.Rows.Count > 0) { samples.ImportRow(cnt_tbl.Rows[0]); DataView dv = samples.DefaultView; dv.Sort = "[" + cnt_tbl.Columns[0].ColumnName + "] ASC"; samples = dv.ToTable(); } // Creo una tabella di appoggio temporanea DataTable cnt_tbl_q = samples.Clone(); // Ciclo per tutti i campioni di samples DateTime now_dt, prec_dt; double now_v, prec_v, liters, flow, seconds; for (int ii = 0; ii < samples.Rows.Count; ii++) { if (ii == 0) continue; // Salta il primo record // Acquisisco i valori attuali e precedenti prec_dt = Convert.ToDateTime(samples.Rows[ii - 1][0]); now_dt = Convert.ToDateTime(samples.Rows[ii][0]); prec_v = Convert.ToDouble(samples.Rows[ii - 1][1]); now_v = Convert.ToDouble(samples.Rows[ii][1]); // Calcolo la differenza in litri seconds = (now_dt - prec_dt).TotalSeconds; liters = (now_v * 1000) - (prec_v * 1000); // Calcolo la portata flow = liters / seconds; // Popolo la tabella cnt_tbl_q.Rows.Add(now_dt, flow); } // Assegno la tabella temporanea a 'samples' samples.Clear(); samples = cnt_tbl_q.Copy(); } DataTable dest = new DataTable(); dest.Columns.Add("timestamp", typeof(DateTime)); dest.Columns.Add("reliable", typeof(bool)); dest.Columns.Add("value", typeof(double)); dest.Columns.Add("measures_id_measures", typeof(int)); dest.Columns.Add("measures_connections_id_odbcdsn", typeof(int)); /************************************************************/ /*** INIZIO PROCEDURA DI INTERPOLAZIONE LINEARE DEI PUNTI ***/ /************************************************************/ // Calcolo il timestamp del valore precedente DateTime first = Convert.ToDateTime(samples.Rows[0][0]); DateTime prec = new DateTime(first.Ticks % interpolation_time.Ticks == 0 ? first.Ticks - interpolation_time.Ticks : (first.Ticks / interpolation_time.Ticks) * interpolation_time.Ticks); // Acquisisco, se presente, ultimo campione precedente a quelli acquisiti, se non esiste, il valore lo considero a zero DataTable tmp = wet_db.ExecCustomQuery("SELECT `timestamp`, `value` FROM data_measures WHERE `timestamp` <= '" + prec.ToString(WetDBConn.MYSQL_DATETIME_FORMAT) + "' AND `measures_id_measures` = " + id_measure.ToString() + " ORDER BY `timestamp` DESC LIMIT 1"); DataRow new_row = samples.NewRow(); if (tmp.Rows.Count == 1) { new_row[0] = Convert.ToDateTime(tmp.Rows[0][0]); new_row[1] = Convert.ToDouble(tmp.Rows[0][1]); } else { new_row[0] = prec; new_row[1] = 0.0d; } samples.Rows.InsertAt(new_row, 0); // Interpolazione lineare Dictionary<DateTime, double> interpolated = WetMath.LinearInterpolation(interpolation_time, WetMath.DataTable2Dictionary(samples, measure_coord.timestamp_column, measure_coord.value_column)); // Riconversione in tabella dati for (int ii = 0; ii < interpolated.Count; ii++) dest.Rows.Add(interpolated.ElementAt(ii).Key, 1, interpolated.ElementAt(ii).Value, id_measure, id_odbc_dsn); /**********************************************************/ /*** FINE PROCEDURA DI INTERPOLAZIONE LINEARE DEI PUNTI ***/ /**********************************************************/ // Inserisco i valori ottenuti nella tabella dati wet_db.TableInsert(dest, "data_measures"); /**********************************/ /*** Calcolo profilo energetico ***/ /**********************************/ // Creo la tabella di appoggio DataTable measures_energy_profile = new DataTable(); measures_energy_profile.Columns.Add("timestamp", typeof(DateTime)); measures_energy_profile.Columns.Add("reliable", typeof(bool)); measures_energy_profile.Columns.Add("value", typeof(double)); measures_energy_profile.Columns.Add("measures_id_measures", typeof(int)); measures_energy_profile.Columns.Add("measures_connections_id_odbcdsn", typeof(int)); // Ciclo per tutti i campioni di portata foreach (DataRow dr in dest.Rows) { // Creo un nuovo record vuoto DataRow mep_r = measures_energy_profile.NewRow(); // Lo popolo calcolando la potenza associata mep_r["timestamp"] = dr["timestamp"]; mep_r["reliable"] = dr["reliable"]; mep_r["value"] = Convert.ToDouble(dr["value"]) * energy_specific_content; mep_r["measures_id_measures"] = dr["measures_id_measures"]; mep_r["measures_connections_id_odbcdsn"] = dr["measures_connections_id_odbcdsn"]; // Lo inserisco nella tabella temporanea measures_energy_profile.Rows.Add(mep_r); } // Inserisco i dati sul DB wet_db.TableInsert(measures_energy_profile, "measures_energy_profile"); } } catch (Exception ex) { WetDebug.GestException(ex); } // Passo il controllo al S.O. per l'attesa if (cancellation_token_source.IsCancellationRequested) return; Sleep(); } // Aggiorno cold_start_counter if (WetEngine.cold_start_counter == 0) WetEngine.cold_start_counter++; }
/// <summary> /// Restituisce la stringa di query base per la misura /// </summary> /// <param name="connection">Connessione</param> /// <param name="measure_coord">Coordinata del database per la misura</param> /// <param name="start_date">Data di inizio nella clausola WHERE</param> /// <param name="stop_date">Data di fine nella clausola WHERE</param> /// <param name="order">Tipo di ordinamento</param> /// <param name="num_records">Numero di records (0 = massimo concesso)</param> /// <returns>Stringa di query</returns> /// <remarks> /// Per stringa base si intende una query compilata nelle specifiche SELECT, FROM e WHERE (solo per tabelle relazionali), /// con la possibilità di aggiungere parametri. /// </remarks> string GetBaseQueryStr(WetDBConn connection, MeasureDBCoord_Struct measure_coord, DateTime start_date, DateTime stop_date, WetDBConn.OrderTypes order, ulong num_records) { string query; switch (connection.GetProvider()) { default: query = string.Empty; break; case WetDBConn.ProviderType.ARCHESTRA_SQL: query = "SELECT "; if (num_records > 0) query += "TOP " + num_records.ToString() + " "; query += "Format(Datetime,'yyyy-MM-dd HH:mm:ss') AS " + measure_coord.timestamp_column + ", Format(Value, '#########0.00') AS '" + measure_coord.value_column + "' FROM " + measure_coord.table_name + " WHERE History.TagName = '" + measure_coord.value_column + "'" + " AND vValue IS NOT NULL " + "AND (Quality = 0 OR Quality = 1) " + "AND (QualityDetail = 192 OR QualityDetail = 202 OR QualityDetail = 64) " + //"AND wwResolution = " + ((int)(config.interpolation_time * 60 * 1000)).ToString() + " " + //"AND wwRetrievalMode = 'Cyclic' " + "AND wwRetrievalMode = 'Full' " + "AND DateTime > CONVERT(datetime, '" + start_date.ToString(WetDBConn.MYSQL_DATETIME_FORMAT) + "', 120) " + "AND DateTime <= CONVERT(datetime, '" + stop_date.ToString(WetDBConn.MYSQL_DATETIME_FORMAT) + "', 120) ORDER BY " + measure_coord.timestamp_column + (order == WetDBConn.OrderTypes.ASC ? " ASC" : " DESC"); break; case WetDBConn.ProviderType.IFIX_SQL: query = "SELECT "; if (num_records > 0) query += "TOP " + num_records.ToString() + " "; query += "* FROM OPENQUERY(IHIST,'SELECT timestamp AS " + measure_coord.timestamp_column + ", value AS " + measure_coord.value_column + " FROM " + measure_coord.table_name + " WHERE Tagname = " + measure_coord.value_column + " AND quality = 100 AND timestamp > ''" + start_date.ToString(WetDBConn.MYSQL_DATETIME_FORMAT) + "'' AND timestamp <= ''" + stop_date.ToString(WetDBConn.MYSQL_DATETIME_FORMAT) + "'' AND samplingmode = LAB ORDER BY " + measure_coord.timestamp_column + (order == WetDBConn.OrderTypes.ASC ? " ASC" : " DESC") + "')"; break; case WetDBConn.ProviderType.EXCEL: query = "SELECT "; if (num_records > 0) query += "TOP " + num_records.ToString() + " "; query += measure_coord.timestamp_column + ", " + measure_coord.value_column + " FROM " + measure_coord.table_name + " WHERE (" + measure_coord.timestamp_column + " > #" + start_date.ToString(WetDBConn.MYSQL_DATETIME_FORMAT) + "# AND " + measure_coord.timestamp_column + " <= #" + stop_date.ToString(WetDBConn.MYSQL_DATETIME_FORMAT) + "#)" + " ORDER BY " + measure_coord.timestamp_column + " " + (order == WetDBConn.OrderTypes.ASC ? "ASC" : "DESC"); break; case WetDBConn.ProviderType.GENERIC_MYSQL: query = "SELECT `" + measure_coord.timestamp_column + "`, `" + measure_coord.value_column + "` FROM " + measure_coord.table_name + " WHERE "; if (measure_coord.relational_id_column != string.Empty) { query += "`" + measure_coord.relational_id_column + "` = "; switch (measure_coord.relational_id_type) { case WetDBConn.PrimaryKeyColumnTypes.REAL: query += measure_coord.relational_id_value.Replace(',', '.'); break; case WetDBConn.PrimaryKeyColumnTypes.DATETIME: query += "'" + Convert.ToDateTime(measure_coord.relational_id_value).ToString(WetDBConn.MYSQL_DATETIME_FORMAT) + "'"; break; case WetDBConn.PrimaryKeyColumnTypes.TEXT: query += "'" + measure_coord.relational_id_value + "'"; break; default: query += measure_coord.relational_id_value; break; } query += " AND "; } query += "(`" + measure_coord.timestamp_column + "` > '" + start_date.ToString(WetDBConn.MYSQL_DATETIME_FORMAT) + "' AND `" + measure_coord.timestamp_column + "` <= '" + stop_date.ToString(WetDBConn.MYSQL_DATETIME_FORMAT) + "')"; query += " ORDER BY `" + measure_coord.timestamp_column + "` " + (order == WetDBConn.OrderTypes.ASC ? "ASC" : "DESC"); if (num_records > 0) query += " LIMIT " + num_records.ToString(); break; } return query; }
/// <summary> /// Restituisce l'ultimo timestamp scritto nel database sorgente /// </summary> /// <param name="connection"></param> /// <param name="start_date">Data di inizio</param> /// <param name="measure_coord"></param> /// <returns></returns> DateTime GetLastSourceSample(WetDBConn connection, DateTime start_date, MeasureDBCoord_Struct measure_coord) { DateTime ret = DateTime.MinValue; try { DataTable dt = connection.ExecCustomQuery(GetBaseQueryStr(connection, measure_coord, start_date, DateTime.Now, WetDBConn.OrderTypes.DESC, 1)); if (dt.Rows.Count == 1) ret = Convert.ToDateTime(dt.Rows[0][0]); } catch (Exception ex) { WetDebug.GestException(ex); } return ret; }
/// <summary> /// Funzione di caricamento /// </summary> protected override void Load() { // Carico la configurazione config = cfg.GetWJ_Agent_Primayer_Config(); // Carico i parametri della configurazione job_sleep_time = config.execution_interval_minutes * 60 * 1000; wetnet_dsn = cfg.GetWetDBDSN(); wet_ftp = new WetFTP(config.ftp_server_name, config.ftp_server_port, config.use_ssl, config.is_passive_connection, config.username, config.password, config.folder); // Istanzio le connessioni wet_db = new WetDBConn(wetnet_dsn, null, null, true); }
/// <summary> /// Funzione di caricamento del job /// </summary> protected override void Load() { // Istanzio la connessione al database wetnet wet_db = new WetDBConn(config.wetdb_dsn, null, null, true); }
/// <summary> /// Funzione di caricamento /// </summary> protected override void Load() { // carico la configurazione config = cfg.GetWJ_Agent_LCF_Config(); // Carico i parametri della configurazione lcf_dsn = config.odbc_dsn; wetnet_dsn = cfg.GetWetDBDSN(); // Istanzio le connessioni ai database lcf_db = new WetDBConn(lcf_dsn, null, null, false); wet_db = new WetDBConn(wetnet_dsn, null, null, true); }
/// <summary> /// Varicamento del job /// </summary> protected override void Load() { // Istanzio la connessione al database wetnet WetConfig cfg = new WetConfig(); wet_db = new WetDBConn(cfg.GetWetDBDSN(), null, null, true); config = cfg.GetWJ_Statistics_Config(); }
/// <summary> /// Caricamento del job /// </summary> protected override void Load() { WetConfig cfg = new WetConfig(); wet_db = new WetDBConn(cfg.GetWetDBDSN(), null, null, true); }
/// <summary> /// Restituisce l'ultimo allarme presente per la misura in questione /// </summary> /// <param name="wet_db">Connessione al database WetNet</param> /// <param name="id_measure">ID della misura</param> /// <param name="id_odbcdsn">ID della connessione</param> /// <param name="date">Data da analizzare</param> /// <returns>Ultimo allarme del giorno specificato</returns> public static AlarmStruct ReadLastAlarmDay(WetDBConn wet_db, int id_measure, int id_odbcdsn, DateTime date) { // Leggo l'ultimo allarme presente DataTable last_alarm_data = wet_db.ExecCustomQuery("SELECT * FROM measures_alarms WHERE `measures_id_measures` = " + id_measure.ToString() + " AND `timestamp` < '" + date.Date.AddDays(1.0d).ToString(WetDBConn.MYSQL_DATE_FORMAT) + "' ORDER BY `timestamp` DESC LIMIT 1"); AlarmStruct last_alarm; if (last_alarm_data.Rows.Count > 0) { last_alarm.timestamp = Convert.ToDateTime(last_alarm_data.Rows[0]["timestamp"]); last_alarm.alarm_type = (AlarmTypes)Convert.ToInt32(last_alarm_data.Rows[0]["alarm_type"]); last_alarm.event_type = (EventTypes)Convert.ToInt32(last_alarm_data.Rows[0]["event_type"]); last_alarm.alarm_value = Convert.ToDouble(last_alarm_data.Rows[0]["alarm_value"]); last_alarm.reference_value = Convert.ToDouble(last_alarm_data.Rows[0]["reference_value"]); string[] strs = Convert.ToString(last_alarm_data.Rows[0]["duration"]).Split(new char[] { ':' }); last_alarm.duration = new TimeSpan(Convert.ToInt32(strs[0]), Convert.ToInt32(strs[1]), Convert.ToInt32(strs[2])); last_alarm.id_measure = Convert.ToInt32(last_alarm_data.Rows[0]["measures_id_measures"]); last_alarm.id_odbcdsn = Convert.ToInt32(last_alarm_data.Rows[0]["measures_connections_id_odbcdsn"]); } else { last_alarm.timestamp = DateTime.Now; last_alarm.alarm_type = AlarmTypes.INVALID; last_alarm.event_type = EventTypes.UNKNOWN; last_alarm.alarm_value = 0.0d; last_alarm.reference_value = 0.0d; last_alarm.duration = new TimeSpan(); last_alarm.id_measure = id_measure; last_alarm.id_odbcdsn = id_odbcdsn; } return last_alarm; }
/// <summary> /// Caricamento del job /// </summary> protected override void Load() { // Istanzio la connessione al database wetnet WetConfig wcfg = new WetConfig(); wet_db = new WetDBConn(wcfg.GetWetDBDSN(), null, null, true); cfg = wcfg.GetWJ_Events_Config(); }