ソース情報
- リポジトリ
- JohnNuwan/EVA_CORE
- ソースの最終更新活動
- 2026年7月18日 08:30
- 検出された SKILL.md の言語
- フランス語
- スター
- 0
- フォーク
- 0
インストール方法
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
ソースファイルを確認
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
メニュー
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/JohnNuwan/EVA_CORE --skill csharp-dotnet-industrialコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
SKILL.md を表示中
SOC 職業分類に基づく
| name | csharp-dotnet-industrial |
| description | Développer en C# pour l'intégration MES et les HMIs Windows. |
| version | 1.1.0 |
| author | EVA |
| license | Privée EVA St-Étienne |
| platforms | ["windows","linux"] |
| metadata | {"tags":["csharp","dotnet","opc-ua","ads","mes","snap7","plctag","wpf","mvvm","database","industrial-integration"],"related_skills":["sql-for-industrial-systems","ot-it-integration-languages","scada-hmi-programming-languages"]} |
Cette compétence encadre l'utilisation de C# et du framework .NET pour concevoir des applications de supervision (HMI), connecter des équipements industriels aux systèmes MES/ERP (OT-IT), et manipuler des protocoles de communication natifs.
En production, un client OPC UA ne doit jamais perdre sa connexion de manière définitive. Le code ci-dessous utilise le SDK officiel OPCFoundation.NetStandard.Opc.Ua et implémente un gestionnaire robuste.
using System;
using System.Threading;
using System.Threading.Tasks;
using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Configuration;
public class EVAOpcClient
{
private Session _session;
private readonly string _endpointUrl;
private readonly ApplicationConfiguration _config;
public EVAOpcClient(string endpointUrl)
{
_endpointUrl = endpointUrl;
_config = CreateOpcConfiguration();
}
private ApplicationConfiguration CreateOpcConfiguration()
{
var config = new ApplicationConfiguration()
{
ApplicationName = "EVA.OpcClient",
ApplicationType = ApplicationType.Client,
ApplicationConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 },
SecurityConfiguration = new SecurityConfiguration
{
AutoAcceptUntrustedCertificates = true,
RejectSHA1SignedCertificates = false
},
TransportQuotas = new TransportQuotas { OperationTimeout = 15000 }
};
config.Validate(ApplicationType.Client).GetAwaiter().GetResult();
return config;
}
public async Task ConnectAsync(CancellationToken ct)
{
var endpoint = new ConfiguredEndpoint(,
CoreClientUtils.SelectEndpoint(_endpointUrl, useSecurity: ),
EndpointConfiguration.Create(_config));
(!ct.IsCancellationRequested)
{
{
Console.WriteLine();
_session = Session.Create(_config, endpoint, , , , , );
_session.KeepAlive += OnSessionKeepAlive;
Console.WriteLine();
;
}
(Exception ex)
{
Console.WriteLine();
Task.Delay(, ct);
}
}
}
{
(e.Status != KeepAliveStatus.Good)
{
Console.WriteLine();
Task.Run(() => ConnectAsync(CancellationToken.None));
}
}
{
(_session == || !_session.Connected)
InvalidOperationException();
nodeId = NodeId(nodeIdStr);
nodesToRead = ReadValueIdCollection {
ReadValueId { NodeId = nodeId, AttributeId = Attributes.Value }
};
response = _session.ReadAsync(, , TimestampsToReturn.Both, nodesToRead, CancellationToken.None);
response.Results[];
}
}
Pour éviter de poller le PLC en permanence, on utilise l'enregistrement de notifications d'ADS (TwinCAT.Ads).
using System;
using TwinCAT.Ads;
public class TwinCatManager : IDisposable
{
private AdsClient _client;
private uint _notificationHandle;
public void Initialize(string netId, int port)
{
_client = new AdsClient();
_client.Connect(netId, port);
// Enregistrement d'une notification sur changement de variable PLC
// Cycle de vérification de 100ms, transmission immédiate sur changement de valeur
_notificationHandle = _client.AddDeviceNotification(
"GVL.TemperatureFour",
new TypeMarshaler(typeof(float)),
new NotificationSettings(AdsTransMode.OnChange, 100, 0),
null
);
_client.AdsNotification += OnAdsNotificationReceived;
}
private void OnAdsNotificationReceived(object sender, AdsNotificationEventArgs e)
{
if (e.UserData is float temp)
{
Console.WriteLine($"[ALERT] Changement de température reçu : {temp} °C");
}
}
public void Dispose()
{
if (_client != null)
{
if (_notificationHandle != )
_client.DeleteDeviceNotification(_notificationHandle);
_client.Disconnect();
_client.Dispose();
}
}
}
En atelier de fabrication, les HMIs WPF doivent être hautement réactives. Le modèle ViewModel ci-dessous met à jour l'interface de manière asynchrone sans bloquer le thread principal.
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
public class MainViewModel : INotifyPropertyChanged
{
private float _pressionCuve;
private string _statutConnexion = "Déconnecté";
public float PressionCuve
{
get => _pressionCuve;
set
{
_pressionCuve = value;
OnPropertyChanged();
}
}
public string StatutConnexion
{
get => _statutConnexion;
set
{
_statutConnexion = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// Boucle d'acquisition asynchrone lancée au démarrage de la fenêtre
public async Task StartAcquisitionLoopAsync(EVAOpcClient client, CancellationToken ct)
{
StatutConnexion = "En cours de connexion...";
await client.ConnectAsync(ct);
StatutConnexion = "Connecté";
while (!ct.IsCancellationRequested)
{
{
data = client.ReadNodeAsync();
(data.Value pression)
{
PressionCuve = pression;
}
Task.Delay(, ct);
}
{
StatutConnexion = ;
client.ConnectAsync(ct);
}
}
}
}
Dapper est préféré à Entity Framework dans les environnements industriels pour des questions de performances brutes de requêtage SQL.
using System;
using System.Data.SqlClient;
using Dapper;
public class ProductionLogger
{
private readonly string _connectionString;
public ProductionLogger(string connectionString)
{
_connectionString = connectionString;
}
public void LogLotProduction(string lotId, float poidsMesure, string operateur)
{
const string query = @"
INSERT INTO T_Tracabilite_Lots (ID_Lot, Date_Enregistrement, Poids, Operateur, Statut)
VALUES (@LotId, @DateEnreg, @Poids, @Operateur, @Statut);";
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
connection.Execute(query, new {
LotId = lotId,
DateEnreg = DateTime.Now,
Poids = poidsMesure,
Operateur = operateur,
Statut = poidsMesure >= 10.0f ? "CONFORME" : "REBUT"
});
}
}
}