Merge branch 'develop'

This commit is contained in:
Samuele E. Locatelli
2020-07-03 14:30:22 +02:00
33 changed files with 1087 additions and 1059 deletions
-74
View File
@@ -1,74 +0,0 @@
{
"confPLC": {
"ipAdrr": "192.168.214.1",
"tipoCpu": "S7300",
"rack": 0,
"slot": 2
},
"TriggerMemConf": "DB700.DBB0",
"parametersList": {
"DB700.DBB8": {
"Column": "Valore 1",
"Index": 1,
"MemConf": "DB700.DBB8",
"DataType": "word",
"memByteSize": 2
},
"DB700.DBB10": {
"Column": "Valore 2",
"Index": 2,
"MemConf": "DB700.DBB10",
"DataType": "word",
"memByteSize": 2
},
"DB700.DBB16": {
"Column": "Valore 3",
"Index": 3,
"MemConf": "DB700.DBB16",
"DataType": "dword",
"memByteSize": 4
},
"DB700.DBB20": {
"Column": "Valore 4",
"Index": 4,
"MemConf": "DB700.DBB20",
"DataType": "dword",
"memByteSize": 4
},
"DB700.DBB32": {
"Column": "Valore 5",
"Index": 5,
"MemConf": "DB700.DBB32",
"DataType": "real",
"memByteSize": 4
},
"DB700.DBB36": {
"Column": "Valore 6",
"Index": 6,
"MemConf": "DB700.DBB36",
"DataType": "real",
"memByteSize": 4
},
"DB700.DBB40": {
"Column": "Valore 7",
"Index": 7,
"MemConf": "DB700.DBB40",
"DataType": "real",
"memByteSize": 4
},
"DB700.DBB48": {
"Column": "Valore 8",
"Index": 8,
"MemConf": "DB700.DBB48",
"DataType": "string",
"memByteSize": 20
}
//"parametersList": {
// "DB701.DBD142": {
// "Column": "Valore assoluto",
// "Index": 7,
// "MemConf": "DB701.DBD142",
// "DataType": "real"
// }
//}
}
@@ -1,67 +0,0 @@
{
"confPLC": {
"ipAdrr": "192.168.0.102",
"tipoCpu": "S71500",
"rack": 0,
"slot": 1
},
"TriggerMemConf": "DB999.DBB0",
"parametersList": {
"DB999.DBB8": {
"Column": "Valore 1",
"Index": 1,
"MemConf": "DB999.DBB8",
"DataType": "word",
"memByteSize": 2
},
"DB999.DBB10": {
"Column": "Valore 2",
"Index": 2,
"MemConf": "DB999.DBB10",
"DataType": "word",
"memByteSize": 2
},
"DB999.DBB16": {
"Column": "Valore 3",
"Index": 3,
"MemConf": "DB999.DBB16",
"DataType": "dword",
"memByteSize": 4
},
"DB999.DBB20": {
"Column": "Valore 4",
"Index": 4,
"MemConf": "DB999.DBB20",
"DataType": "dword",
"memByteSize": 4
},
"DB999.DBB32": {
"Column": "Valore 5",
"Index": 5,
"MemConf": "DB999.DBB32",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB36": {
"Column": "Valore 6",
"Index": 6,
"MemConf": "DB999.DBB36",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB40": {
"Column": "Valore 7",
"Index": 7,
"MemConf": "DB999.DBB40",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB48": {
"Column": "Valore 8",
"Index": 8,
"MemConf": "DB999.DBB48",
"DataType": "string",
"memByteSize": 20
}
}
}
-67
View File
@@ -1,67 +0,0 @@
{
"confPLC": {
"ipAdrr": "192.168.0.102",
"tipoCpu": "S71500",
"rack": 0,
"slot": 1
},
"TriggerMemConf": "DB999.DBB0",
"parametersList": {
"DB999.DBB8": {
"Column": "Valore 1",
"Index": 1,
"MemConf": "DB999.DBB8",
"DataType": "word",
"memByteSize": 2
},
"DB999.DBB10": {
"Column": "Valore 2",
"Index": 2,
"MemConf": "DB999.DBB10",
"DataType": "word",
"memByteSize": 2
},
"DB999.DBB16": {
"Column": "Valore 3",
"Index": 3,
"MemConf": "DB999.DBB16",
"DataType": "dword",
"memByteSize": 4
},
"DB999.DBB20": {
"Column": "Valore 4",
"Index": 4,
"MemConf": "DB999.DBB20",
"DataType": "dword",
"memByteSize": 4
},
"DB999.DBB32": {
"Column": "Valore 5",
"Index": 5,
"MemConf": "DB999.DBB32",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB36": {
"Column": "Valore 6",
"Index": 6,
"MemConf": "DB999.DBB36",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB40": {
"Column": "Valore 7",
"Index": 7,
"MemConf": "DB999.DBB40",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB48": {
"Column": "Valore 8",
"Index": 8,
"MemConf": "DB999.DBB48",
"DataType": "string",
"memByteSize": 20
}
}
}
-17
View File
@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MHT_Siemens
{
public static class Constants
{
#region memorie configurate staticamente
public const string RESOURCE_DIRECTORY = @"IOB.WIN.FileExp.Config.";
public const string CONFIG_PATH = RESOURCE_DIRECTORY + @"setup.json";
#endregion
}
}
-235
View File
@@ -1,235 +0,0 @@
namespace MHT_Siemens
{
partial class IOB_Exporter
{
/// <summary>
/// Variabile di progettazione necessaria.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Pulire le risorse in uso.
/// </summary>
/// <param name="disposing">ha valore true se le risorse gestite devono essere eliminate, false in caso contrario.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Codice generato da Progettazione Windows Form
/// <summary>
/// Metodo necessario per il supporto della finestra di progettazione. Non modificare
/// il contenuto del metodo con l'editor di codice.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(IOB_Exporter));
this.txtCsvPath = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.lblPlcIp = new System.Windows.Forms.Label();
this.txtIP = new System.Windows.Forms.TextBox();
this.txtSlot = new System.Windows.Forms.TextBox();
this.lblPlcSlot = new System.Windows.Forms.Label();
this.txtRack = new System.Windows.Forms.TextBox();
this.lblPlcRack = new System.Windows.Forms.Label();
this.lblPlcCpu = new System.Windows.Forms.Label();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.tsslApp = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar();
this.txtCpuType = new System.Windows.Forms.TextBox();
this.txtLog = new System.Windows.Forms.TextBox();
this.statusStrip1.SuspendLayout();
this.SuspendLayout();
//
// txtCsvPath
//
this.txtCsvPath.Enabled = false;
this.txtCsvPath.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtCsvPath.Location = new System.Drawing.Point(28, 40);
this.txtCsvPath.Name = "txtCsvPath";
this.txtCsvPath.Size = new System.Drawing.Size(172, 20);
this.txtCsvPath.TabIndex = 0;
this.txtCsvPath.Text = "c:\\TMP\\OutputFile.csv";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(25, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(47, 13);
this.label1.TabIndex = 1;
this.label1.Text = "CSV File";
//
// lblPlcIp
//
this.lblPlcIp.AutoSize = true;
this.lblPlcIp.Location = new System.Drawing.Point(279, 24);
this.lblPlcIp.Name = "lblPlcIp";
this.lblPlcIp.Size = new System.Drawing.Size(42, 13);
this.lblPlcIp.TabIndex = 2;
this.lblPlcIp.Text = "IP Addr";
//
// txtIP
//
this.txtIP.Enabled = false;
this.txtIP.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtIP.Location = new System.Drawing.Point(340, 21);
this.txtIP.Name = "txtIP";
this.txtIP.Size = new System.Drawing.Size(106, 20);
this.txtIP.TabIndex = 3;
this.txtIP.Text = "192.168.0.102";
this.txtIP.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// txtSlot
//
this.txtSlot.Enabled = false;
this.txtSlot.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtSlot.Location = new System.Drawing.Point(499, 47);
this.txtSlot.Margin = new System.Windows.Forms.Padding(2);
this.txtSlot.Name = "txtSlot";
this.txtSlot.Size = new System.Drawing.Size(29, 20);
this.txtSlot.TabIndex = 10;
this.txtSlot.Text = "1";
this.txtSlot.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// lblPlcSlot
//
this.lblPlcSlot.AutoSize = true;
this.lblPlcSlot.Location = new System.Drawing.Point(462, 49);
this.lblPlcSlot.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblPlcSlot.Name = "lblPlcSlot";
this.lblPlcSlot.Size = new System.Drawing.Size(25, 13);
this.lblPlcSlot.TabIndex = 8;
this.lblPlcSlot.Text = "Slot";
//
// txtRack
//
this.txtRack.Enabled = false;
this.txtRack.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtRack.Location = new System.Drawing.Point(499, 21);
this.txtRack.Margin = new System.Windows.Forms.Padding(2);
this.txtRack.Name = "txtRack";
this.txtRack.Size = new System.Drawing.Size(29, 20);
this.txtRack.TabIndex = 11;
this.txtRack.Text = "0";
this.txtRack.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// lblPlcRack
//
this.lblPlcRack.AutoSize = true;
this.lblPlcRack.Location = new System.Drawing.Point(462, 23);
this.lblPlcRack.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblPlcRack.Name = "lblPlcRack";
this.lblPlcRack.Size = new System.Drawing.Size(33, 13);
this.lblPlcRack.TabIndex = 9;
this.lblPlcRack.Text = "Rack";
//
// lblPlcCpu
//
this.lblPlcCpu.AutoSize = true;
this.lblPlcCpu.Location = new System.Drawing.Point(279, 49);
this.lblPlcCpu.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblPlcCpu.Name = "lblPlcCpu";
this.lblPlcCpu.Size = new System.Drawing.Size(56, 13);
this.lblPlcCpu.TabIndex = 7;
this.lblPlcCpu.Text = "CPU Type";
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsslApp,
this.toolStripProgressBar1});
this.statusStrip1.Location = new System.Drawing.Point(0, 421);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(658, 22);
this.statusStrip1.TabIndex = 12;
this.statusStrip1.Text = "statusStrip1";
//
// tsslApp
//
this.tsslApp.Name = "tsslApp";
this.tsslApp.Size = new System.Drawing.Size(16, 17);
this.tsslApp.Text = "...";
//
// toolStripProgressBar1
//
this.toolStripProgressBar1.Name = "toolStripProgressBar1";
this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16);
//
// txtCpuType
//
this.txtCpuType.Enabled = false;
this.txtCpuType.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtCpuType.Location = new System.Drawing.Point(340, 47);
this.txtCpuType.Name = "txtCpuType";
this.txtCpuType.Size = new System.Drawing.Size(106, 20);
this.txtCpuType.TabIndex = 13;
this.txtCpuType.Text = "S71200";
this.txtCpuType.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// txtLog
//
this.txtLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtLog.BackColor = System.Drawing.Color.Black;
this.txtLog.Enabled = false;
this.txtLog.ForeColor = System.Drawing.SystemColors.MenuHighlight;
this.txtLog.Location = new System.Drawing.Point(13, 82);
this.txtLog.Multiline = true;
this.txtLog.Name = "txtLog";
this.txtLog.Size = new System.Drawing.Size(633, 336);
this.txtLog.TabIndex = 14;
this.txtLog.Text = "...";
//
// IOB_Exporter
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(658, 443);
this.Controls.Add(this.txtLog);
this.Controls.Add(this.txtCpuType);
this.Controls.Add(this.statusStrip1);
this.Controls.Add(this.txtSlot);
this.Controls.Add(this.lblPlcSlot);
this.Controls.Add(this.txtRack);
this.Controls.Add(this.lblPlcRack);
this.Controls.Add(this.lblPlcCpu);
this.Controls.Add(this.txtIP);
this.Controls.Add(this.lblPlcIp);
this.Controls.Add(this.label1);
this.Controls.Add(this.txtCsvPath);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "IOB_Exporter";
this.Text = "MAPO IOB Exporter";
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox txtCsvPath;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label lblPlcIp;
private System.Windows.Forms.TextBox txtIP;
private System.Windows.Forms.TextBox txtSlot;
private System.Windows.Forms.Label lblPlcSlot;
private System.Windows.Forms.TextBox txtRack;
private System.Windows.Forms.Label lblPlcRack;
private System.Windows.Forms.Label lblPlcCpu;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripStatusLabel tsslApp;
private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1;
private System.Windows.Forms.TextBox txtCpuType;
private System.Windows.Forms.TextBox txtLog;
}
}
-531
View File
@@ -1,531 +0,0 @@
using Newtonsoft.Json;
using NLog;
using S7.Net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Windows.Forms;
namespace MHT_Siemens
{
public partial class IOB_Exporter : Form
{
#region oggetti di base
/// <summary>
/// configurazione principale proxy
/// </summary>
protected dataProxy currDataProxy;
/// <summary>
/// Oggetto PLC da ri-utilizzare...
/// </summary>
protected Plc currPLC;
/// <summary>
/// parametri di connessione
/// </summary>
protected connParam parametri;
/// <summary>
/// oggetto logging
/// </summary>
public static Logger lg;
/// <summary>
/// oggetto uiTimer x gestione refresh UI
/// </summary>
protected Timer uiTimer = new Timer();
/// <summary>
/// oggetto uiTimer x sampling file testuale
/// </summary>
protected Timer sampleTimer = new Timer();
/// <summary>
/// oggetto uiTimer x verifiche
/// </summary>
protected Timer checkTimer = new Timer();
/// <summary>
/// Contatore per decidere quando loggare la lettura del file
/// </summary>
protected int loaderLogCounter = 30;
/// <summary>
/// file delle conf attivo
/// </summary>
protected string setupFile = "setup.json";
/// <summary>
/// Ultimi valori registrati da file
/// </summary>
protected Dictionary<string, string> prevValues;
/// <summary>
/// valori correntemente letti dal file
/// </summary>
protected Dictionary<string, string> currValues;
#endregion
#region inizializazione
public IOB_Exporter()
{
InitializeComponent();
myInit();
}
private void myInit()
{
lg = LogManager.GetCurrentClassLogger();
tsslApp.Text = $"{utils.CRS("appName")}";
fixVisibility();
prevValues = new Dictionary<string, string>();
currValues = new Dictionary<string, string>();
loadMemConf();
loadPlc();
startUiTimer();
startSampleTimer();
startCheckTimer();
}
private void fixVisibility()
{
bool showParams = false;
#if DEBUG
showParams = true;
#endif
lblPlcIp.Visible = showParams;
lblPlcCpu.Visible = showParams;
lblPlcRack.Visible = showParams;
lblPlcSlot.Visible = showParams;
txtIP.Visible = showParams;
txtCpuType.Visible = showParams;
txtRack.Visible = showParams;
txtSlot.Visible = showParams;
}
private void startUiTimer()
{
uiTimer.Interval = 20;
uiTimer.Tick += UiTimer_Tick;
uiTimer.Start();
}
private void startSampleTimer()
{
int sampleTimerMs = utils.CRI("sampleTimerMs");
sampleTimerMs = sampleTimerMs < 100 ? 100 : sampleTimerMs;
sampleTimer.Interval = sampleTimerMs;
sampleTimer.Tick += SampleTimer_Tick;
sampleTimer.Start();
}
private void startCheckTimer()
{
// ogni 5 minuti watchdog
checkTimer.Interval = sampleTimer.Interval * 60;
checkTimer.Tick += CheckTimer_Tick;
checkTimer.Start();
}
/// <summary>
/// init PLC
/// </summary>
private void loadPlc()
{
lgInfo("Refreshing connection...");
parametri = currDataProxy.confPLC;
// ora tento avvio PLC... SE PING OK...
if (testPing() == IPStatus.Success)
{
try
{
lgInfo($"PLC parameters: CPU {parametri.tipoCpu} | IP: {parametri.ipAdrr} | R/S: {parametri.rack}/{parametri.slot}");
currPLC = new Plc(parametri.tipoCpu, parametri.ipAdrr, parametri.rack, parametri.slot);
currPLC.Open();
if (currPLC.IsConnected)
{
lgInfo("PLC Connected!");
}
else
{
lgInfo("Connection error!");
}
}
catch (Exception exc)
{
lgError(exc, "Errore in INIT PLC");
}
}
}
/// <summary>
/// Init conf memoria
/// </summary>
protected void loadMemConf()
{
lgInfo("Starting loadMemConf");
if (File.Exists(setupFile))
{
lgInfo("Setup File found!");
try
{
StreamReader reader = new StreamReader(setupFile);
string jsonData = reader.ReadToEnd();
if (!string.IsNullOrEmpty(jsonData))
{
currDataProxy = JsonConvert.DeserializeObject<dataProxy>(jsonData);
lgInfo("Completed data deserialization");
}
reader.Close();
}
catch
{
currDataProxy = null;
}
}
// se non esistesse creo un nuovo file default
if (currDataProxy == null)
{
lgInfo($"File NOT found: {setupFile} - creating new");
dataConf newParam = new dataConf()
{
Column = "Valore assoluto",
Index = 8,
MemConf = "DB701.DBD142",
DataType = "real"
};
Dictionary<string, dataConf> paramList = new Dictionary<string, dataConf>();
paramList.Add(newParam.MemConf, newParam);
// creo nuovo obj...
currDataProxy = new dataProxy()
{
csvFilePath = @"c:\zz\prova1.csv",
csvFileEnableWrite = true,
csvSeparator = ';',
confPLC = new connParam()
{
ipAdrr = "192.168.0.102",
tipoCpu = CpuType.S71500,
rack = 0,
slot = 1
},
parametersList = paramList
};
// salvo!
string json = JsonConvert.SerializeObject(currDataProxy);
//write string to file
File.WriteAllText(setupFile, json);
lgInfo($"Setup File saved: {setupFile}");
}
// adesso valorizzo tutti i parametri
txtCsvPath.Text = currDataProxy.csvFilePath;
txtIP.Text = currDataProxy.confPLC.ipAdrr;
txtCpuType.Text = $"{currDataProxy.confPLC.tipoCpu}";
txtRack.Text = $"{currDataProxy.confPLC.rack}";
txtSlot.Text = $"{currDataProxy.confPLC.slot}";
}
#endregion
#region metodi ricorrenti
private void UiTimer_Tick(object sender, EventArgs e)
{
toolStripProgressBar1.ProgressBar.Value++;
if (toolStripProgressBar1.ProgressBar.Value >= toolStripProgressBar1.ProgressBar.Maximum)
{
toolStripProgressBar1.ProgressBar.Value = 0;
}
}
private void CheckTimer_Tick(object sender, EventArgs e)
{
// loggo!
lgInfo("Program Alive control...");
//verifico PLC
if (currPLC.IsConnected)
{
lgInfo("PLC Connected!");
}
else
{
lgInfo("Connection error!");
}
// loggo che COMUNQUE forzo scrittura su PLC!
lgInfo("Forced PLC write");
// invio a PLC
saveToPLC();
}
private void SampleTimer_Tick(object sender, EventArgs e)
{
// rileggo il file
reloadFromFile();
// verifico valore confrontando con i precedenti...
if (dataChanged())
{
// loggo!
lgInfo("Data Change on File");
// invio a PLC
saveToPLC();
}
}
#endregion
#region helper methods
/// <summary>
/// salva i dati sul PLC
/// </summary>
private void saveToPLC()
{
// invio TUTTI i dati al PLC secondo configurazione...
if (testCncConn())
{
// decodifico memoria...
memAddress memoria = null;
double valore = -999;
foreach (var item in currValues)
{
memoria = new memAddress(item.Key);
double.TryParse(item.Value, out valore);
// hard coded REAL!!!
byte[] DB_Byte = new byte[4];
S7.Net.Types.Double.ToByteArray(valore).CopyTo(DB_Byte, 0);
currPLC.WriteBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, DB_Byte);
// loggo invio al PLC!
lgInfo($"Value sent to PLC: {item.Key} | {valore}");
}
}
}
/// <summary>
/// Effettua comparazioen dati vecchi/nuovi
/// </summary>
/// <returns></returns>
private bool dataChanged()
{
bool answ = false;
// se i 2 vettori sono diversi
if (currValues.Count != prevValues.Count)
{
resetPrevVal();
return true;
}
// verifico ogni singolo valore...
foreach (var item in currValues)
{
// cerco...
if (prevValues.ContainsKey(item.Key))
{
// verifico se diversi --> trovato cambio!
answ = currValues[item.Key] != prevValues[item.Key];
}
else
{
answ = true;
}
// se ho cambiamenti --> esco!
if (answ)
{
// salvo ed esco subito
resetPrevVal();
return true;
}
}
return answ;
}
/// <summary>
/// Refresh oggetto valori precedenti
/// </summary>
private void resetPrevVal()
{
// salvo ed esco subito
prevValues = new Dictionary<string, string>();
foreach (var item in currValues)
{
prevValues.Add(item.Key, item.Value);
}
}
/// <summary>
/// Effettua rilettura da file
/// </summary>
protected void reloadFromFile()
{
if (File.Exists(currDataProxy.csvFilePath))
{
// leggo...
using (StreamReader sr = new StreamReader(currDataProxy.csvFilePath))
{
string currentLine;
//se ha header salto la prima riga...
if (currDataProxy.csvFileEnableWrite)
{
if ((currentLine = sr.ReadLine()) == null)
{
// vuoto: loggo ed esco!
lgError("Errore intestazione vuota!");
return;
}
}
// ora leggo la riga successiva... SE !=null
if ((currentLine = sr.ReadLine()) != null)
{
// splitto riga e cerco valore...
var valori = currentLine.Split(currDataProxy.csvSeparator);
// cerco parametri!
try
{
foreach (var item in currDataProxy.parametersList)
{
// cerco!
if (valori.Count() >= item.Value.Index)
{
upsertValue(item.Key, valori[item.Value.Index]);
}
}
}
catch (Exception exc)
{
lgError($"Eccezione i decodifica riga misura: {Environment.NewLine}{exc}");
}
loaderLogCounter--;
if (loaderLogCounter < 0)
{
// loggo che ho letto file e che contiene una certa riga...
lgInfo($"Verifica periodica riga file, contenuto:{Environment.NewLine}{currentLine}");
loaderLogCounter = 30;
}
}
else
{
// vuoto: loggo ed esco!
lgError("Errore riga vuota!");
return;
}
loaderLogCounter--;
if (loaderLogCounter < 0)
{
// loggo che ho letto file e che contiene una certa riga...
lgInfo("Check periodico file presente OK");
loaderLogCounter = 30;
}
}
}
else
{
lgError($"Errore! file non trovato: {currDataProxy.csvFilePath}");
}
}
protected void upsertValue(string key, string value)
{
// cerco se ci sia... aggiorno!
if (currValues.ContainsKey(key))
{
currValues[key] = value;
}
// altrimenti aggiungo
else
{
currValues.Add(key, value);
}
}
/// <summary>
/// test ping all'indirizzo impostato nei parametri
/// </summary>
/// <returns></returns>
private IPStatus testPing()
{
IPStatus answ = IPStatus.Unknown; ;
IPAddress address;
PingReply reply;
Ping pingSender = new Ping();
address = IPAddress.Loopback;
IPAddress.TryParse(parametri.ipAdrr, out address);
reply = pingSender.Send(address, 100);
answ = reply.Status;
return answ;
}
/// <summary>
/// Test connessione CNC
/// </summary>
/// <returns></returns>
private bool testCncConn()
{
bool answ = false;
IPStatus pingStatus = testPing();
// se passa il ping faccio il resto...
if (pingStatus != IPStatus.Success)
{
lgError("Errore ping");
}
else
{
if (!currPLC.IsConnected)
{
currPLC.Open();
}
if (!currPLC.IsConnected)
{
lgError("Errore connessione");
}
else
{
answ = true;
}
}
return answ;
}
private void appenRTLog(string contenuto)
{
// se troppe righe trimmo...
string fullLog = limitLine2show($"{contenuto}{Environment.NewLine}{txtLog.Text}");
// update
txtLog.Text = fullLog;
}
/// <summary>
/// Effettua un trim della stringa al numero max di linee da mostrare a video
/// </summary>
/// <param name="newString"></param>
/// <returns></returns>
public string limitLine2show(string newString)
{
if (!string.IsNullOrEmpty(newString))
{
// se num righe superiore a limite trimmo...
if (newString.Split('\n').Length > 50)
{
//int idx = newString.LastIndexOf('\r');
int idx = newString.LastIndexOf(Environment.NewLine);
newString = newString.Substring(0, idx);
}
}
return newString;
}
protected void lgInfo(string contenuto)
{
lg.Info(contenuto);
appenRTLog(contenuto);
}
protected void lgError(string contenuto)
{
lg.Error(contenuto);
appenRTLog(contenuto);
}
protected void lgError(Exception exc, string contenuto)
{
lg.Error(exc, contenuto);
appenRTLog(contenuto);
}
#endregion
}
}
-54
View File
@@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MHT_Siemens
{
/// <summary>
/// classe costruzione dataproxy
/// </summary>
public class dataProxy
{
/// <summary>
/// Configurazione PLC
/// </summary>
public connParam confPLC { get; set; }
/// <summary>
/// Area memoria da usare come trigger x scrittura
/// </summary>
public string TriggerMemConf { get; set; } = "";
/// <summary>
/// Elenco parametri da salvare
/// </summary>
public Dictionary<string, dataConf> parametersList { get; set; } = new Dictionary<string, dataConf>();
}
/// <summary>
/// Configurazione item memoria gestito
/// </summary>
public class dataConf
{
/// <summary>
/// Colonna (intestazione) se non presente indice
/// </summary>
public string Column { get; set; } = "";
/// <summary>
/// Indice colonna (se presente usa questo)
/// </summary>
public int Index { get; set; } = -1;
/// <summary>
/// Area memoria da cui leggere i dati
/// </summary>
public string MemConf { get; set; } = "";
/// <summary>
/// Tipo di dati
/// </summary>
public string DataType { get; set; } = "";
/// <summary>
/// Dimensione memoria in Byte
/// </summary>
public int memByteSize { get; set; } = 1;
}
}
+1 -1
View File
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30002.166
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IOB.WIN.FileExp", "IOB-WIN-FILE-EXP\IOB.WIN.FileExp.csproj", "{958CB938-3860-49D3-8B16-15ED0E9FE2FB}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IOB.WIN.FileExp", "IOB.WIN.FileExp\IOB.WIN.FileExp.csproj", "{958CB938-3860-49D3-8B16-15ED0E9FE2FB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+82
View File
@@ -0,0 +1,82 @@
{
"confPLC": {
"ipAdrr": "192.168.214.1",
"tipoCpu": "S7300",
"rack": 0,
"slot": 2
},
"triggerList": {
"DB700.DBB0": {
"Column": "Trigger",
"MemConf": "DB700.DBB0",
"DataType": "byte",
"memByteSize": 1,
"TriggerVal": "01"
}
},
"parametersList": {
"DB700.DBB8": {
"Column": "Valore 1",
"Index": 1,
"MemConf": "DB700.DBB8",
"DataType": "word",
"memByteSize": 2
},
"DB700.DBB10": {
"Column": "Valore 2",
"Index": 2,
"MemConf": "DB700.DBB10",
"DataType": "word",
"memByteSize": 2
},
"DB700.DBB16": {
"Column": "Valore 3",
"Index": 3,
"MemConf": "DB700.DBB16",
"DataType": "dword",
"memByteSize": 4
},
"DB700.DBB20": {
"Column": "Valore 4",
"Index": 4,
"MemConf": "DB700.DBB20",
"DataType": "dword",
"memByteSize": 4
},
"DB700.DBB32": {
"Column": "Valore 5",
"Index": 5,
"MemConf": "DB700.DBB32",
"DataType": "real",
"memByteSize": 4
},
"DB700.DBB36": {
"Column": "Valore 6",
"Index": 6,
"MemConf": "DB700.DBB36",
"DataType": "real",
"memByteSize": 4
},
"DB700.DBB40": {
"Column": "Valore 7",
"Index": 7,
"MemConf": "DB700.DBB40",
"DataType": "real",
"memByteSize": 4
},
"DB700.DBB48": {
"Column": "Valore 8",
"Index": 8,
"MemConf": "DB700.DBB48",
"DataType": "string",
"memByteSize": 20
}
//"parametersList": {
// "DB701.DBD142": {
// "Column": "Valore assoluto",
// "Index": 7,
// "MemConf": "DB701.DBD142",
// "DataType": "real"
// }
//}
}
@@ -0,0 +1,67 @@
{
"confPLC": {
"ipAdrr": "192.168.0.102",
"tipoCpu": "S71500",
"rack": 0,
"slot": 1
},
"triggerList": {
"DB999.DBB0": {
"Column": "Trigger",
"MemConf": "DB999.DBB0",
"DataType": "byte",
"memByteSize": 1,
"TriggerVal": "01"
}
},
"parametersList": {
"DB999.DBB8": {
"Column": "Valore 1",
"MemConf": "DB999.DBB8",
"DataType": "word",
"memByteSize": 2
},
"DB999.DBB10": {
"Column": "Valore 2",
"MemConf": "DB999.DBB10",
"DataType": "word",
"memByteSize": 2
},
"DB999.DBB16": {
"Column": "Valore 3",
"MemConf": "DB999.DBB16",
"DataType": "dword",
"memByteSize": 4
},
"DB999.DBB20": {
"Column": "Valore 4",
"MemConf": "DB999.DBB20",
"DataType": "dword",
"memByteSize": 4
},
"DB999.DBB32": {
"Column": "Valore 5",
"MemConf": "DB999.DBB32",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB36": {
"Column": "Valore 6",
"MemConf": "DB999.DBB36",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB40": {
"Column": "Valore 7",
"MemConf": "DB999.DBB40",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB48": {
"Column": "Valore 8",
"MemConf": "DB999.DBB48",
"DataType": "string",
"memByteSize": 20
}
}
}
+67
View File
@@ -0,0 +1,67 @@
{
"confPLC": {
"ipAdrr": "192.168.0.102",
"tipoCpu": "S71500",
"rack": 0,
"slot": 1
},
"triggerList": {
"DB999.DBB0": {
"Column": "Trigger",
"MemConf": "DB999.DBB0",
"DataType": "byte",
"memByteSize": 1,
"TriggerVal": "01"
}
},
"parametersList": {
"DB999.DBB8": {
"Column": "Valore 1",
"MemConf": "DB999.DBB8",
"DataType": "word",
"memByteSize": 2
},
"DB999.DBB10": {
"Column": "Valore 2",
"MemConf": "DB999.DBB10",
"DataType": "word",
"memByteSize": 2
},
"DB999.DBB16": {
"Column": "Valore 3",
"MemConf": "DB999.DBB16",
"DataType": "dword",
"memByteSize": 4
},
"DB999.DBB20": {
"Column": "Valore 4",
"MemConf": "DB999.DBB20",
"DataType": "dword",
"memByteSize": 4
},
"DB999.DBB32": {
"Column": "Valore 5",
"MemConf": "DB999.DBB32",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB36": {
"Column": "Valore 6",
"MemConf": "DB999.DBB36",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB40": {
"Column": "Valore 7",
"MemConf": "DB999.DBB40",
"DataType": "real",
"memByteSize": 4
},
"DB999.DBB48": {
"Column": "Valore 8",
"MemConf": "DB999.DBB48",
"DataType": "string",
"memByteSize": 20
}
}
}
+236
View File
@@ -0,0 +1,236 @@
namespace IOB.WIN.FileExp
{
partial class IOB_Exporter
{
/// <summary>
/// Variabile di progettazione necessaria.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Pulire le risorse in uso.
/// </summary>
/// <param name="disposing">ha valore true se le risorse gestite devono essere eliminate, false in caso contrario.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Codice generato da Progettazione Windows Form
/// <summary>
/// Metodo necessario per il supporto della finestra di progettazione. Non modificare
/// il contenuto del metodo con l'editor di codice.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(IOB_Exporter));
this.txtCsvPath = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.lblPlcIp = new System.Windows.Forms.Label();
this.txtIP = new System.Windows.Forms.TextBox();
this.txtSlot = new System.Windows.Forms.TextBox();
this.lblPlcSlot = new System.Windows.Forms.Label();
this.txtRack = new System.Windows.Forms.TextBox();
this.lblPlcRack = new System.Windows.Forms.Label();
this.lblPlcCpu = new System.Windows.Forms.Label();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.tsslApp = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar();
this.txtCpuType = new System.Windows.Forms.TextBox();
this.txtLog = new System.Windows.Forms.TextBox();
this.statusStrip1.SuspendLayout();
this.SuspendLayout();
//
// txtCsvPath
//
this.txtCsvPath.Enabled = false;
this.txtCsvPath.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtCsvPath.Location = new System.Drawing.Point(28, 40);
this.txtCsvPath.Name = "txtCsvPath";
this.txtCsvPath.Size = new System.Drawing.Size(172, 20);
this.txtCsvPath.TabIndex = 0;
this.txtCsvPath.Text = "c:\\TMP\\OutputFile.csv";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(25, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(47, 13);
this.label1.TabIndex = 1;
this.label1.Text = "CSV File";
//
// lblPlcIp
//
this.lblPlcIp.AutoSize = true;
this.lblPlcIp.Location = new System.Drawing.Point(279, 24);
this.lblPlcIp.Name = "lblPlcIp";
this.lblPlcIp.Size = new System.Drawing.Size(42, 13);
this.lblPlcIp.TabIndex = 2;
this.lblPlcIp.Text = "IP Addr";
//
// txtIP
//
this.txtIP.Enabled = false;
this.txtIP.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtIP.Location = new System.Drawing.Point(340, 21);
this.txtIP.Name = "txtIP";
this.txtIP.Size = new System.Drawing.Size(106, 20);
this.txtIP.TabIndex = 3;
this.txtIP.Text = "192.168.0.102";
this.txtIP.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// txtSlot
//
this.txtSlot.Enabled = false;
this.txtSlot.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtSlot.Location = new System.Drawing.Point(499, 47);
this.txtSlot.Margin = new System.Windows.Forms.Padding(2);
this.txtSlot.Name = "txtSlot";
this.txtSlot.Size = new System.Drawing.Size(29, 20);
this.txtSlot.TabIndex = 10;
this.txtSlot.Text = "1";
this.txtSlot.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// lblPlcSlot
//
this.lblPlcSlot.AutoSize = true;
this.lblPlcSlot.Location = new System.Drawing.Point(462, 49);
this.lblPlcSlot.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblPlcSlot.Name = "lblPlcSlot";
this.lblPlcSlot.Size = new System.Drawing.Size(25, 13);
this.lblPlcSlot.TabIndex = 8;
this.lblPlcSlot.Text = "Slot";
//
// txtRack
//
this.txtRack.Enabled = false;
this.txtRack.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtRack.Location = new System.Drawing.Point(499, 21);
this.txtRack.Margin = new System.Windows.Forms.Padding(2);
this.txtRack.Name = "txtRack";
this.txtRack.Size = new System.Drawing.Size(29, 20);
this.txtRack.TabIndex = 11;
this.txtRack.Text = "0";
this.txtRack.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// lblPlcRack
//
this.lblPlcRack.AutoSize = true;
this.lblPlcRack.Location = new System.Drawing.Point(462, 23);
this.lblPlcRack.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblPlcRack.Name = "lblPlcRack";
this.lblPlcRack.Size = new System.Drawing.Size(33, 13);
this.lblPlcRack.TabIndex = 9;
this.lblPlcRack.Text = "Rack";
//
// lblPlcCpu
//
this.lblPlcCpu.AutoSize = true;
this.lblPlcCpu.Location = new System.Drawing.Point(279, 49);
this.lblPlcCpu.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblPlcCpu.Name = "lblPlcCpu";
this.lblPlcCpu.Size = new System.Drawing.Size(56, 13);
this.lblPlcCpu.TabIndex = 7;
this.lblPlcCpu.Text = "CPU Type";
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsslApp,
this.toolStripProgressBar1});
this.statusStrip1.Location = new System.Drawing.Point(0, 421);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(658, 22);
this.statusStrip1.TabIndex = 12;
this.statusStrip1.Text = "statusStrip1";
//
// tsslApp
//
this.tsslApp.Name = "tsslApp";
this.tsslApp.Size = new System.Drawing.Size(16, 17);
this.tsslApp.Text = "...";
//
// toolStripProgressBar1
//
this.toolStripProgressBar1.Name = "toolStripProgressBar1";
this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16);
//
// txtCpuType
//
this.txtCpuType.Enabled = false;
this.txtCpuType.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtCpuType.Location = new System.Drawing.Point(340, 47);
this.txtCpuType.Name = "txtCpuType";
this.txtCpuType.Size = new System.Drawing.Size(106, 20);
this.txtCpuType.TabIndex = 13;
this.txtCpuType.Text = "S71200";
this.txtCpuType.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// txtLog
//
this.txtLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtLog.BackColor = System.Drawing.Color.Black;
this.txtLog.ForeColor = System.Drawing.SystemColors.MenuHighlight;
this.txtLog.Location = new System.Drawing.Point(13, 73);
this.txtLog.Multiline = true;
this.txtLog.Name = "txtLog";
this.txtLog.ReadOnly = true;
this.txtLog.Size = new System.Drawing.Size(633, 345);
this.txtLog.TabIndex = 14;
this.txtLog.Text = "- - -";
this.txtLog.WordWrap = false;
//
// IOB_Exporter
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(658, 443);
this.Controls.Add(this.txtLog);
this.Controls.Add(this.txtCpuType);
this.Controls.Add(this.statusStrip1);
this.Controls.Add(this.txtSlot);
this.Controls.Add(this.lblPlcSlot);
this.Controls.Add(this.txtRack);
this.Controls.Add(this.lblPlcRack);
this.Controls.Add(this.lblPlcCpu);
this.Controls.Add(this.txtIP);
this.Controls.Add(this.lblPlcIp);
this.Controls.Add(this.label1);
this.Controls.Add(this.txtCsvPath);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "IOB_Exporter";
this.Text = "MAPO IOB Exporter";
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox txtCsvPath;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label lblPlcIp;
private System.Windows.Forms.TextBox txtIP;
private System.Windows.Forms.TextBox txtSlot;
private System.Windows.Forms.Label lblPlcSlot;
private System.Windows.Forms.TextBox txtRack;
private System.Windows.Forms.Label lblPlcRack;
private System.Windows.Forms.Label lblPlcCpu;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripStatusLabel tsslApp;
private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1;
private System.Windows.Forms.TextBox txtCpuType;
private System.Windows.Forms.TextBox txtLog;
}
}
+564
View File
@@ -0,0 +1,564 @@
using Newtonsoft.Json;
using NLog;
using S7.Net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Windows.Forms;
namespace IOB.WIN.FileExp
{
public partial class IOB_Exporter : Form
{
#region oggetti di base
/// <summary>
/// configurazione principale proxy
/// </summary>
protected dataProxy currDataProxy;
/// <summary>
/// Oggetto PLC da ri-utilizzare...
/// </summary>
protected Plc currPLC;
/// <summary>
/// parametri di connessione
/// </summary>
protected connParam parametri;
/// <summary>
/// oggetto logging
/// </summary>
public static Logger lg;
/// <summary>
/// oggetto uiTimer x gestione refresh UI
/// </summary>
protected Timer uiTimer = new Timer();
/// <summary>
/// oggetto uiTimer x sampling file testuale
/// </summary>
protected Timer sampleTimer = new Timer();
/// <summary>
/// oggetto uiTimer x verifiche
/// </summary>
protected Timer checkTimer = new Timer();
/// <summary>
/// Contatore per decidere quando loggare la lettura del file
/// </summary>
protected int loaderLogCounter = 30;
/// <summary>
/// Directory base delle risorse (virtuale)
/// </summary>
protected const string RESOURCE_DIRECTORY = @"IOB.WIN.FileExp.Config.";
/// <summary>
/// file delle conf attivo
/// </summary>
protected const string setupFile = RESOURCE_DIRECTORY + @"setup.json";
/// <summary>
/// File output x salvataggio
/// </summary>
protected string outFilePath = @"C:\TMP\OutFile.csv";
/// <summary>
/// Ultimi valori registrati da file
/// </summary>
protected Dictionary<string, string> prevValues;
/// <summary>
/// valori correntemente letti dal file
/// </summary>
protected Dictionary<string, string> currValues;
#endregion
#region inizializazione
public IOB_Exporter()
{
InitializeComponent();
myInit();
}
private void myInit()
{
lg = LogManager.GetCurrentClassLogger();
txtLog.Text = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} ----------------------------------------------------";
tsslApp.Text = $"{utils.CRS("appName")}";
fixVisibility();
prevValues = new Dictionary<string, string>();
currValues = new Dictionary<string, string>();
loadMemConf();
loadPlc();
startUiTimer();
startCheckTimer();
startPlcSampleTimer();
}
/// <summary>
/// Fix visibilità parametri conf in debug
/// </summary>
private void fixVisibility()
{
bool showParams = false;
#if DEBUG
showParams = true;
#endif
lblPlcIp.Visible = showParams;
lblPlcCpu.Visible = showParams;
lblPlcRack.Visible = showParams;
lblPlcSlot.Visible = showParams;
txtIP.Visible = showParams;
txtCpuType.Visible = showParams;
txtRack.Visible = showParams;
txtSlot.Visible = showParams;
}
/// <summary>
/// avvio timer update UI
/// </summary>
private void startUiTimer()
{
// setup progressBar
toolStripProgressBar1.ProgressBar.Step = 5;
// UI: ogni 100 ms
uiTimer.Interval = 100;
uiTimer.Tick += UiTimer_Tick;
uiTimer.Start();
}
/// <summary>
/// Avvio timer controlli periodici (PLC; file...)
/// </summary>
private void startCheckTimer()
{
// check preliminare...
doPeriodChecks();
// poi ogni 3 minuti replico (watchdog)
checkTimer.Interval = 3 * 60 * 1000;
checkTimer.Tick += CheckTimer_Tick;
checkTimer.Start();
}
/// <summary>
/// Avvio timer campionamento PLC
/// </summary>
private void startPlcSampleTimer()
{
int sampleTimerMs = utils.CRI("sampleTimerMs");
// limite in lettura a 5 hz
sampleTimerMs = sampleTimerMs < 200 ? 200 : sampleTimerMs;
sampleTimer.Interval = sampleTimerMs;
sampleTimer.Tick += plcSampleTimer_Tick;
sampleTimer.Start();
}
/// <summary>
/// init PLC
/// </summary>
private void loadPlc()
{
lgInfo("Refreshing connection...");
parametri = currDataProxy.confPLC;
// ora tento avvio PLC... SE PING OK...
if (testPing() == IPStatus.Success)
{
try
{
lgInfo($"PLC parameters: CPU {parametri.tipoCpu} | IP: {parametri.ipAdrr} | R/S: {parametri.rack}/{parametri.slot}");
currPLC = new Plc(parametri.tipoCpu, parametri.ipAdrr, parametri.rack, parametri.slot);
currPLC.Open();
if (currPLC.IsConnected)
{
lgInfo("PLC Connected!");
}
else
{
lgInfo("Connection error!");
}
}
catch (Exception exc)
{
lgError(exc, "Errore in INIT PLC");
}
}
}
/// <summary>
/// Init conf memoria
/// </summary>
protected void loadMemConf()
{
lgInfo("Starting loadMemConf");
// recupero conf da resources
Assembly myAssembly = Assembly.GetExecutingAssembly();
//var resNames = myAssembly.GetManifestResourceNames();
using (Stream confStream = myAssembly.GetManifestResourceStream(setupFile))
{
using (StreamReader fileReader = new StreamReader(confStream))
{
string jsonData = fileReader.ReadToEnd();
if (!string.IsNullOrEmpty(jsonData))
{
lgInfo("Setup OK!");
try
{
currDataProxy = JsonConvert.DeserializeObject<dataProxy>(jsonData);
// verifica num max variabili (MAX 8...)
if (currDataProxy.parametersList.Count > 8)
{
lgInfo("Invalid config, reduce params list");
while (currDataProxy.parametersList.Count > 8)
{
currDataProxy.parametersList.Remove(currDataProxy.parametersList.LastOrDefault().Key);
}
}
lgInfo("Completed data deserialization");
}
catch
{
currDataProxy = null;
}
}
}
}
if (currDataProxy == null)
{
lgInfo($"Setup File NOT found: {setupFile} - creating new");
dataConf newParam = new dataConf()
{
Column = "Valore assoluto",
MemConf = "DB701.DBD142",
DataType = "real"
};
Dictionary<string, dataConf> paramList = new Dictionary<string, dataConf>();
paramList.Add(newParam.MemConf, newParam);
// creo nuovo obj...
currDataProxy = new dataProxy()
{
triggerList = null,
confPLC = new connParam()
{
ipAdrr = "192.168.0.102",
tipoCpu = CpuType.S71500,
rack = 0,
slot = 1
},
parametersList = paramList
};
}
// adesso valorizzo tutti i parametri
outFilePath = utils.CRS("csvFilePath");
txtCsvPath.Text = outFilePath;
txtIP.Text = currDataProxy.confPLC.ipAdrr;
txtCpuType.Text = $"{currDataProxy.confPLC.tipoCpu}";
txtRack.Text = $"{currDataProxy.confPLC.rack}";
txtSlot.Text = $"{currDataProxy.confPLC.slot}";
}
#endregion
#region metodi ricorrenti
/// <summary>
/// Esecuzione task UI
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void UiTimer_Tick(object sender, EventArgs e)
{
toolStripProgressBar1.ProgressBar.Value++;
if (toolStripProgressBar1.ProgressBar.Value >= toolStripProgressBar1.ProgressBar.Maximum)
{
toolStripProgressBar1.ProgressBar.Value = 0;
}
}
/// <summary>
/// Esecuzione task di verifica periodica
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CheckTimer_Tick(object sender, EventArgs e)
{
doPeriodChecks();
}
/// <summary>
/// Effettua controlli periodici su PLC, file...
/// </summary>
private void doPeriodChecks()
{
// loggo!
lgInfo("Program Alive control...");
//verifico PLC
if (currPLC.IsConnected)
{
lgInfo("PLC Connected!");
}
else
{
lgInfo("Connection error!");
}
// verifico esistenza file sennò creo
if (!File.Exists(outFilePath))
{
lgInfo("Target file not found: creating new!");
string fileContent = "";
// se non esiste --> creo con headers se richiesto!
if (utils.CRB("csvHeader"))
{
foreach (var item in currDataProxy.parametersList)
{
fileContent += $"{item.Value.Column}{utils.CRS("csvSeparator")}";
}
// elimino ultimo separatore...
fileContent = fileContent.Substring(0, fileContent.Length - 1);
}
// scrivo!
File.WriteAllText(outFilePath, fileContent);
}
}
/// <summary>
/// Esecuzione task di campionamento
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void plcSampleTimer_Tick(object sender, EventArgs e)
{
// leggo aree di memoria triggers dal PLC
reloadTriggersFromPLC();
// verifico valore confrontando con i precedenti...
if (dataChanged())
{
// invio su file
saveToFile();
}
}
#endregion
#region helper methods
/// <summary>
/// salva i dati sul FILE in append
/// </summary>
private void saveToFile()
{
// FIXME TODO salvare su file
#if false
// invio TUTTI i dati al PLC secondo configurazione...
if (testCncConn())
{
// decodifico memoria...
memAddress memoria = null;
double valore = -999;
foreach (var item in currValues)
{
memoria = new memAddress(item.Key);
double.TryParse(item.Value, out valore);
// hard coded REAL!!!
byte[] DB_Byte = new byte[4];
S7.Net.Types.Double.ToByteArray(valore).CopyTo(DB_Byte, 0);
currPLC.WriteBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, DB_Byte);
// loggo invio al PLC!
lgInfo($"Value sent to PLC: {item.Key} | {valore}");
}
}
#endif
}
/// <summary>
/// Effettua comparazioen dati vecchi/nuovi
/// </summary>
/// <returns></returns>
private bool dataChanged()
{
bool answ = false;
// se i 2 vettori sono diversi in numero
if (currValues.Count != prevValues.Count)
{
resetPrevVal();
// loggo!
lgInfo("Trigger activated on PLC: different count");
return true;
}
// verifico ogni singolo valore...
foreach (var item in currValues)
{
// cerco...
if (prevValues.ContainsKey(item.Key))
{
// verifico se diversi --> trovato cambio, indago!
if (currValues[item.Key] != prevValues[item.Key])
{
// loggo!
lgInfo($"Difference found: {prevValues[item.Key]} --> {currValues[item.Key]}");
// solo se il NUOVO valore è pari al trigger cercato...
if (currValues[item.Key] == currDataProxy.triggerList[item.Key].TriggerVal)
{
lgInfo($"Valid Trigger found: {currDataProxy.triggerList[item.Key].TriggerVal}");
answ = true;
}
else
{
// senza segnalare cambio recepisco nuovo valore...
resetPrevVal();
}
}
}
else
{
lgInfo($"Trigger activated on PLC: new value found --> {item.Key}");
answ = true;
}
// se ho cambiamenti --> esco!
if (answ)
{
// salvo ed esco subito
resetPrevVal();
return true;
}
}
return answ;
}
/// <summary>
/// Refresh oggetto valori precedenti
/// </summary>
private void resetPrevVal()
{
// salvo ed esco subito
prevValues = new Dictionary<string, string>();
foreach (var item in currValues)
{
prevValues.Add(item.Key, item.Value);
}
}
/// <summary>
/// Effettua rilettura da PLC dei triggers data
/// </summary>
protected void reloadTriggersFromPLC()
{
// init
memAddress memoria = null;
int numByte = 0;
// leggo triggers dal PLC
foreach (var item in currDataProxy.triggerList)
{
memoria = new memAddress(item.Value.MemConf);
numByte = item.Value.memByteSize;
// leggo!
var currMem = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte);
// salvo
upsertValue(item.Value.MemConf, BitConverter.ToString(currMem));
}
}
protected void upsertValue(string key, string value)
{
// cerco se ci sia... aggiorno!
if (currValues.ContainsKey(key))
{
currValues[key] = value;
}
// altrimenti aggiungo
else
{
currValues.Add(key, value);
}
}
/// <summary>
/// test ping all'indirizzo impostato nei parametri
/// </summary>
/// <returns></returns>
private IPStatus testPing()
{
IPStatus answ = IPStatus.Unknown; ;
IPAddress address;
PingReply reply;
Ping pingSender = new Ping();
address = IPAddress.Loopback;
IPAddress.TryParse(parametri.ipAdrr, out address);
reply = pingSender.Send(address, 100);
answ = reply.Status;
return answ;
}
/// <summary>
/// Test connessione CNC
/// </summary>
/// <returns></returns>
private bool testCncConn()
{
bool answ = false;
IPStatus pingStatus = testPing();
// se passa il ping faccio il resto...
if (pingStatus != IPStatus.Success)
{
lgError("Errore ping");
}
else
{
if (!currPLC.IsConnected)
{
currPLC.Open();
}
if (!currPLC.IsConnected)
{
lgError("Errore connessione");
}
else
{
answ = true;
}
}
return answ;
}
/// <summary>
/// Aggiorno log in area console
/// </summary>
/// <param name="contenuto"></param>
private void appendRTLog(string contenuto)
{
// se troppe righe trimmo...
string fullLog = limitLine2show($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {contenuto}{Environment.NewLine}{txtLog.Text}");
// update
txtLog.Text = fullLog;
}
/// <summary>
/// Effettua un trim della stringa al numero max di linee da mostrare a video
/// </summary>
/// <param name="newString"></param>
/// <returns></returns>
public string limitLine2show(string newString)
{
if (!string.IsNullOrEmpty(newString))
{
// se num righe superiore a limite trimmo...
if (newString.Split('\n').Length > 50)
{
//int idx = newString.LastIndexOf('\r');
int idx = newString.LastIndexOf(Environment.NewLine);
newString = newString.Substring(0, idx);
}
}
return newString;
}
protected void lgInfo(string contenuto)
{
lg.Info(contenuto);
appendRTLog($"| INFO | {contenuto}");
}
protected void lgError(string contenuto)
{
lg.Error(contenuto);
appendRTLog($"| ERROR | {contenuto}");
}
protected void lgError(Exception exc, string contenuto)
{
lg.Error(exc, contenuto);
appendRTLog($"| EXC | {contenuto}");
}
#endregion
}
}
@@ -6,8 +6,8 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{958CB938-3860-49D3-8B16-15ED0E9FE2FB}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>MHT_Siemens</RootNamespace>
<AssemblyName>MHT-Siemens</AssemblyName>
<RootNamespace>IOB.WIN.FileExp</RootNamespace>
<AssemblyName>IOB.WIN.FileExp</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
@@ -65,7 +65,6 @@
</ItemGroup>
<ItemGroup>
<Compile Include="connParam.cs" />
<Compile Include="Constants.cs" />
<Compile Include="dataProxy.cs" />
<Compile Include="memAddress.cs" />
<Compile Include="IOB-Exporter.cs">
@@ -4,7 +4,7 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MHT_Siemens
namespace IOB.WIN.FileExp
{
static class Program
{
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build
// usando l'asterisco '*' come illustrato di seguito:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.2005.28")]
[assembly: AssemblyFileVersion("1.1.2005.28")]
[assembly: AssemblyVersion("1.2.2007.31")]
[assembly: AssemblyFileVersion("1.2.2007.31")]
@@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace MHT_Siemens.Properties {
namespace IOB.WIN.FileExp.Properties {
using System;
@@ -39,7 +39,7 @@ namespace MHT_Siemens.Properties {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MHT_Siemens.Properties.Resources", typeof(Resources).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("IOB.WIN.FileExp.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
@@ -8,11 +8,11 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace MHT_Siemens.Properties {
namespace IOB.WIN.FileExp.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.6.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

Before

Width:  |  Height:  |  Size: 273 KiB

After

Width:  |  Height:  |  Size: 273 KiB

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Before

Width:  |  Height:  |  Size: 273 KiB

After

Width:  |  Height:  |  Size: 273 KiB

@@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MHT_Siemens
namespace IOB.WIN.FileExp
{
public class connParam
{
+58
View File
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IOB.WIN.FileExp
{
/// <summary>
/// classe costruzione dataproxy
/// </summary>
public class dataProxy
{
/// <summary>
/// Configurazione PLC
/// </summary>
public connParam confPLC { get; set; }
/// <summary>
/// Aree memoria da usare come trigger x scatenare salvataggio valori
/// </summary>
public Dictionary<string, triggerConf> triggerList { get; set; } = new Dictionary<string, triggerConf>();
/// <summary>
/// Elenco parametri da salvare
/// </summary>
public Dictionary<string, dataConf> parametersList { get; set; } = new Dictionary<string, dataConf>();
}
public class triggerConf:dataConf
{
/// <summary>
/// Valore trigger che scatena evento (SE trovato post cambio valore)
/// </summary>
public string TriggerVal { get; set; } = "";
}
/// <summary>
/// Configurazione item memoria gestito
/// </summary>
public class dataConf
{
/// <summary>
/// Colonna (intestazione) se non presente indice
/// </summary>
public string Column { get; set; } = "";
/// <summary>
/// Area memoria da cui leggere i dati
/// </summary>
public string MemConf { get; set; } = "";
/// <summary>
/// Tipo di dati
/// </summary>
public string DataType { get; set; } = "";
/// <summary>
/// Dimensione memoria in Byte
/// </summary>
public int memByteSize { get; set; } = 1;
}
}
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MHT_Siemens
namespace IOB.WIN.FileExp
{
public class memAddress
{
@@ -8,7 +8,7 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MHT_Siemens
namespace IOB.WIN.FileExp
{
public class utils
{