Files
2025-06-17 09:01:04 +02:00

444 lines
15 KiB
C#

using IOB_MAN.Core;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ThirdParty.Json.LitJson;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace IOB_MAN
{
public partial class FluxLogData : Form
{
#region Public Fields
/// <summary>
/// Gestore processi redis
/// </summary>
public RedisIobCache redisMan;
#endregion Public Fields
#region Public Constructors
/// <summary>
/// Init form
/// </summary>
/// <param name="CodServer">Cod server con cui comunica</param>
/// <param name="CodIob">Cod IOB gestito</param>
/// <param name="appNameExt">Nome app gestita (es IOB-WIN-NEXT)</param>
public FluxLogData(Dictionary<string, string> iobList, Dictionary<string, TargetConfig> targetList, string CodServer, string CodIOB, string AppNameExt)
{
codServer = CodServer;
codIob = CodIOB;
appNameExt = AppNameExt;
IobList = iobList;
TargetList = targetList;
// init REDIS
redisMan = new RedisIobCache(codServer, codIob, appNameExt);
InitializeComponent();
paramsInit();
}
#endregion Public Constructors
#region Internal Methods
/// <summary>
/// Caricamento dati
/// </summary>
internal void LoadData()
{
// leggo i dati
loadRedisBaseData();
loadConfData();
dgvFluxRec.DataSource = FluxLogRecList;
dgvFluxDisp.DataSource = FluxLogConfList;
dgvFluxDetList.Visible = false;
dgvFluxDetPareto.Visible = false;
setParamEdit(false);
}
#endregion Internal Methods
#region Private Fields
/// <summary>
/// Codice IOB selezionato
/// </summary>
private string appNameExt = "";
/// <summary>
/// Codice IOB selezionato
/// </summary>
private string codIob = "ND";
/// <summary>
/// Codice server
/// </summary>
private string codServer = "";
private string confFile = "";
/// <summary>
/// Conf memoria IOB
/// </summary>
private plcMemMapExt currMem = new plcMemMapExt();
private DateTime dtReq = DateTime.Now;
/// <summary>
/// Binding source degli elementi gestiti..
/// </summary>
private BindingSource FluxLogConfList = new BindingSource();
/// <summary>
/// Binding source degli elementi registrati..
/// </summary>
private BindingSource FluxLogRecList = new BindingSource();
/// <summary>
/// Binding source degli elementi come lista x singolo flusso..
/// </summary>
private BindingSource FluxLogValList = new BindingSource();
/// <summary>
/// Binding source degli elementi pareto x singolo flusso..
/// </summary>
private BindingSource FluxLogValPareto = new BindingSource();
private int idxSel = -1;
/// <summary>
/// Dizionario IOB (nome IOB + tipo target EXE)
/// </summary>
private Dictionary<string, string> IobList = new Dictionary<string, string>();
private MapoSDK.dataConfTSVC selArea = new MapoSDK.dataConfTSVC();
/// <summary>
/// Codice flusso selezionato
/// </summary>
private string selCodFlux = "";
/// <summary>
/// Dizionario applicazioni target da lanciare
/// </summary>
private Dictionary<string, TargetConfig> TargetList = new Dictionary<string, TargetConfig>();
#endregion Private Fields
#region Private Methods
private void btnCancel_Click(object sender, EventArgs e)
{
FluxLogValPareto.Clear();
FluxLogValList.Clear();
if (idxSel >= 0)
{
dgvFluxRec.Rows[idxSel].Selected = false;
}
idxSel = -1;
confFile = "";
selCodFlux = "";
dgvFluxDetList.Visible = false;
dgvFluxDetPareto.Visible = false;
// rileggo conf
loadConfData();
setParamEdit(false);
}
/// <summary>
/// Salvataggio file di conf...
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSave_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(confFile))
{
// aggiorna valori prima di salvare del record corrente
updateEditVals();
// scrivo file!
if (File.Exists(confFile))
{
DateTime adesso = DateTime.Now;
// faccio backup
string fileNameOnly = Path.GetFileName(confFile);
string baseDir = Path.GetDirectoryName(confFile);
string bcfFile = Path.Combine(baseDir, $"{fileNameOnly}_{adesso:yyMMdd-HHmmss}.bck");
File.Copy(confFile, bcfFile);
// serializzo e salvo...
JsonSerializerSettings jsSet = new JsonSerializerSettings()
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
Culture = CultureInfo.InvariantCulture
};
string rawData = JsonConvert.SerializeObject(currMem, jsSet);
File.WriteAllText(confFile, rawData);
}
// rileggo conf
loadConfData();
setParamEdit(false);
}
}
private void dgvFluxRec_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex >= 0)
{
// se c'era già un altro record in editing --> salva modifica
if (idxSel >= 0)
{
// aggiorna valori del record modificato
updateEditVals();
}
// recupero i dati del nuovo record selezionato
idxSel = e.RowIndex;
dgvFluxRec.Rows[idxSel].Selected = true;
StatsFL.ParetoVals selRow = (StatsFL.ParetoVals)FluxLogRecList[idxSel];
selCodFlux = selRow.Valore;
loadRedisDGV();
displayConf();
}
}
private void dgvFluxRec_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
FluxLogRecList.Sort = dgvFluxRec.Columns[e.ColumnIndex].Name;
dgvFluxRec.Invalidate();
}
/// <summary>
/// Caricamento parte di conf memoria da file caricato
/// </summary>
/// <exception cref="NotImplementedException"></exception>
private void displayConf()
{
if (currMem.mMapRead.ContainsKey(selCodFlux))
{
setParamEdit(true);
selArea = currMem.mMapRead[selCodFlux];
chkSendEnabled.Checked = selArea.sendEnabled;
txtPeriod.Text = $"{selArea.period}";
txtMinVal.Text = $"{selArea.minVal}";
txtMaxVal.Text = $"{selArea.maxVal}";
txtDesc.Text = selArea.description;
txtUM.Text = selArea.unit;
if (selArea.thresholdAbs != null)
{
txtThreshAbs.Text = $"{selArea.thresholdAbs}";
}
if (selArea.thresholdPerc != null)
{
txtThreshPerc.Text = $"{selArea.thresholdPerc}";
}
cbFunc.SelectedItem = selArea.func;
}
else
{
setParamEdit(false);
}
}
/// <summary>
/// Impostazione editabilità parametri
/// </summary>
/// <param name="editEnabled"></param>
private void setParamEdit(bool editEnabled)
{
// reset preliminare valori a vuoto...
chkSendEnabled.Checked = false;
txtPeriod.Text = "";
txtMinVal.Text = "";
txtMaxVal.Text = "";
txtDesc.Text = "";
txtUM.Text = "";
txtThreshAbs.Text = "";
txtThreshPerc.Text = "";
// imposto abilitazione
txtPeriod.Enabled = editEnabled;
txtMinVal.Enabled = editEnabled;
txtMaxVal.Enabled = editEnabled;
txtThreshAbs.Enabled = editEnabled;
txtThreshPerc.Enabled = editEnabled;
txtDesc.Enabled = editEnabled;
txtUM.Enabled = editEnabled;
chkSendEnabled.Enabled = editEnabled;
cbFunc.Enabled = editEnabled;
btnSave.Enabled = editEnabled;
}
private void dtSelector_ValueChanged(object sender, EventArgs e)
{
dtReq = dtSelector.Value;
loadRedisBaseData();
}
/// <summary>
/// Legge elenco conf parametri da file json dell'IOB corrente
/// </summary>
private void loadConfData()
{
// cerco IOB
if (IobList.ContainsKey(codIob))
{
string tipoIob = IobList[codIob];
// cerco target
if (TargetList.ContainsKey(tipoIob))
{
// recupero info dell'IOB...
var iobData = TargetList.FirstOrDefault(x => x.Key == tipoIob);
// calcolo percorso file di conf
confFile = Path.Combine(iobData.Value.ConfDir, $"{codIob}.json");
if (File.Exists(confFile))
{
string rawData = File.ReadAllText(confFile);
if (rawData != null)
{
try
{
currMem = JsonConvert.DeserializeObject<plcMemMapExt>(rawData);
}
catch { }
}
}
}
// carico anche i valori della lista di VC ammessi...
cbFunc.DataSource = Enum.GetValues(typeof(MapoSDK.VC_func));
}
}
/// <summary>
/// Legge dati da area redis
/// </summary>
private void loadRedisBaseData()
{
FluxLogRecList.Clear();
// recupero in primis elenco pareto info
string rKey = $"{redisMan.redIobTrackKey}:DayStats:{dtReq:yyMMdd}";
var dictFL = redisMan.redGetHashDict(rKey);
// se trovo riordino...
if (dictFL != null & dictFL.Count > 0)
{
List<StatsFL.ParetoVals> dailyPareto = dictFL
.Select(x => new StatsFL.ParetoVals(x.Key, x.Value))
.OrderByDescending(x => x.Freq)
.ToList();
foreach (var item in dailyPareto)
{
FluxLogRecList.Add(item);
}
}
}
/// <summary>
/// Caricamento dati dettaglio CodFlux da REDIS
/// </summary>
private void loadRedisDGV()
{
FluxLogValPareto.Clear();
FluxLogValList.Clear();
// rileggo dettagli
string rKey = $"{redisMan.redIobTrackKey}:DetailStats:{dtReq:yyMMdd}:{selCodFlux}";
var rawPareto = redisMan.redGetHashDict(rKey);
// se trovo riordino...
if (rawPareto != null & rawPareto.Count > 0)
{
List<StatsFL.ParetoVals> dataPareto = rawPareto
.Select(x => new StatsFL.ParetoVals(x.Key, x.Value))
.OrderByDescending(x => x.Freq)
.ToList();
foreach (var item in dataPareto)
{
FluxLogValPareto.Add(item);
}
}
rKey = $"{redisMan.redIobTrackKey}:DataLog:{dtReq:yyMMdd}:{selCodFlux}";
var rawLog = redisMan.redGetHashDict(rKey);
// se trovo riordino...
if (rawLog != null & rawLog.Count > 0)
{
List<StatsFL.DataLog> detailLog = rawLog
.Select(x => new StatsFL.DataLog(x.Key, x.Value))
.OrderByDescending(x => x.DataOra)
.ToList();
foreach (var item in detailLog)
{
FluxLogValList.Add(item);
}
}
dgvFluxDetList.DataSource = FluxLogValList;
dgvFluxDetPareto.DataSource = FluxLogValPareto;
dgvFluxDetList.Visible = true;
dgvFluxDetPareto.Visible = true;
// predispongo larghezze colonne
dgvFluxDetList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dgvFluxDetList.AutoResizeColumns();
dgvFluxDetList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dgvFluxDetList.AllowUserToResizeColumns = true;
}
private void paramsInit()
{
DateTime oggi = DateTime.Today;
dtReq = oggi;
dtSelector.MinDate = dtReq.AddMonths(-1);
dtSelector.MaxDate = dtReq;
lblCodIob.Text = codIob;
}
private void updateEditVals()
{
// recupero area di memoria e modifico...
selArea = currMem.mMapRead[selCodFlux];
int iVal = 0;
double dVal = 0;
if (int.TryParse(txtPeriod.Text, out iVal))
{
selArea.period = iVal;
}
if (double.TryParse(txtMinVal.Text, out dVal))
{
selArea.minVal = dVal;
}
if (double.TryParse(txtMaxVal.Text, out dVal))
{
selArea.maxVal = dVal;
}
if (!string.IsNullOrEmpty(txtThreshAbs.Text))
{
if (double.TryParse(txtThreshAbs.Text, out dVal))
{
selArea.thresholdAbs = dVal;
}
}
if (!string.IsNullOrEmpty(txtThreshPerc.Text))
{
if (double.TryParse(txtThreshPerc.Text, out dVal))
{
selArea.thresholdPerc = dVal;
}
}
selArea.sendEnabled = chkSendEnabled.Checked;
selArea.description = txtDesc.Text;
selArea.unit = txtUM.Text;
selArea.func = (MapoSDK.VC_func)cbFunc.SelectedItem;
}
#endregion Private Methods
}
}