Bonjour, j'ai 350 compteurs smartESOX de chez APATOR et 33 concentrateurs.
Cependant je n'arrive pas à me connecter à plusieurs compteurs sur la même adresse IP et le même port. J'ai donc crée un programme de test qui est composé de 3 compteurs qui partagent la même adresse ip et le même port.
Je réussi à me connecter au premier compteur mais les deux autres compteurs échouent au niveau de _reader.InitializeConnection(); .
Vous trouverez ci dessous le code de mon programme de test. j'utilise c#
*MeterConnection*
using Gurux.Common;
using Gurux.DLMS;
using Gurux.DLMS.Enums;
using Gurux.DLMS.Objects;
using Gurux.DLMS.Reader;
using Gurux.DLMS.Secure;
using Gurux.Net;
using System;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Threading;
namespace MeterConnection
{
public class MeterConnection : IDisposable
{
private GXNet _media; // ← Plus readonly pour pouvoir recréer
private readonly GXDLMSSecureClient _client;
private GXDLMSReader _reader;
private readonly string _meterName;
private readonly string _serverIp;
private readonly int _port;
private readonly object _lock = new object();
public bool IsConnected { get; private set; }
public MeterConnection(
string serverIp,
int port,
int clientAddress,
int PhysicalAddress,
string authenticationKey,
string unicastKey,
string password,
string meterName)
{
_meterName = meterName;
_serverIp = serverIp;
_port = port;
var authKey = GXCommon.HexToBytes(authenticationKey);
var blockKey = GXCommon.HexToBytes(unicastKey);
byte[] systemTitle = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
_client = new GXDLMSSecureClient(
true, // useLogicalNameReferencing
clientAddress, // clientAddress
PhysicalAddress, // serverAddress
Authentication.HighGMAC, // authentication
null, // password
InterfaceType.HDLC
);
_client.Ciphering.Security = Security.AuthenticationEncryption;
_client.Ciphering.AuthenticationKey = authKey;
_client.Ciphering.BlockCipherKey = blockKey;
_client.ServerAddress = GXDLMSClient.GetServerAddress(1, PhysicalAddress);
//_client.Ciphering.SystemTitle = systemTitle;
}
public void Connect()
{
lock (_lock)
{
if (IsConnected) return;
Console.WriteLine($"[{_meterName}] Connexion...");
// ← CRUCIAL : Crée une NOUVELLE instance GXNet à chaque fois
_media = new GXNet(NetworkType.Tcp, _serverIp, _port);
_media.Open();
_reader = new GXDLMSReader(_client, _media, TraceLevel.Info, null);
// Augmente les timeouts pour le debug
_reader.WaitTime = 10000; // 10 secondes
_reader.RetryCount = 3;
try
{
_reader.InitializeConnection();
IsConnected = true;
Console.WriteLine($"[{_meterName}] ✅ Connecté");
}
catch (Exception ex)
{
// Nettoyage immédiat en cas d'échec
Cleanup();
throw;
}
}
}
public object Read(string logicalName, int attributeIndex)
{
lock (_lock)
{
if (!IsConnected)
throw new InvalidOperationException("Non connecté");
var obj = CreateObject(logicalName);
return _reader.Read(obj, attributeIndex);
}
}
private GXDLMSObject CreateObject(string logicalName)
{
var parts = logicalName.Split('.');
int c = int.Parse(parts[2]);
ObjectType objectType = c switch
{
0 => ObjectType.Data,
1 => ObjectType.Register,
3 => ObjectType.RegisterActivation,
4 => ObjectType.ExtendedRegister,
5 => ObjectType.DemandRegister,
7 => ObjectType.ProfileGeneric,
_ => ObjectType.Data
};
var obj = GXDLMSClient.CreateObject(objectType);
obj.LogicalName = logicalName;
return obj;
}
public void Disconnect()
{
lock (_lock)
{
if (!IsConnected) return;
Console.WriteLine($"[{_meterName}] Déconnexion...");
Cleanup();
Console.WriteLine($"[{_meterName}] ✅ Déconnecté");
}
}
/// <summary>
/// Nettoyage complet des ressources
/// </summary>
private void Cleanup()
{
// 1. Ferme le reader (Release + Disconnect)
try
{
_reader?.Close();
}
catch (Exception ex)
{
Console.WriteLine($"[{_meterName}] Warning Close: {ex.Message}");
}
// 2. Ferme explicitement la media
try
{
_media?.Close();
}
catch (Exception ex)
{
Console.WriteLine($"[{_meterName}] Warning Media.Close: {ex.Message}");
}
// 3. Dispose la media
try
{
_media?.Dispose();
}
catch (Exception ex)
{
Console.WriteLine($"[{_meterName}] Warning Media.Dispose: {ex.Message}");
}
_reader = null;
_media = null;
IsConnected = false;
}
public void Dispose()
{
Disconnect();
}
}
}
*Program*
using Gurux.DLMS;
using Gurux.DLMS.Enums;
using System;
using System.Collections.Generic;
using System.Threading.Tasks; // ← Ajout explicite
namespace MeterConnection
{
class Program
{
// ← Retourne Task pour éviter CS0161
static async System.Threading.Tasks.Task Main(string[] args)
{
const string SERVER_IP = "10.60.7.67";
const int SERVER_PORT = 81;
var meters = new[]
{
new { Name = "58013888", ClientAddr = 2, AuthenticationKey = "97AD945D9557B254BAB1DE191F166543", UnicastKey = "40313A67A3D041A11A40C6E56356E51F" , Password="57356D6E6E62736A"},
new { Name = "58014042", ClientAddr = 2, AuthenticationKey = "798D2CE6917EA619B5A08DC3BA2EC8C7", UnicastKey = "B8E2A992E4C38CE7540380A25742792B" , Password="4444635669774B45"},
new { Name = "58014028", ClientAddr = 2, AuthenticationKey = "0917D0DD4F1FAE7159FAF6AF34CA4067", UnicastKey = "63D2983BE91FB3BE8475550A6315FFE1" , Password="6C34717876616939"}
};
var connections = new List<MeterConnection>();
try
{
foreach (var m in meters)
{
var PhysicalAddress = int.Parse(m.Name.Substring(m.Name.Length - 4)) + 100;
var conn = new MeterConnection(
SERVER_IP,
SERVER_PORT,
m.ClientAddr,
PhysicalAddress,
m.AuthenticationKey,
m.UnicastKey,
m.Password,
m.Name
);
connections.Add(conn);
conn.Connect();
await System.Threading.Tasks.Task.Delay(300);
}
foreach (var conn in connections)
{
try
{
var datetime = conn.Read("0.0.1.0.0.255", 2);
Console.WriteLine($"{conn}: DateTime = {datetime}");
}
catch (Exception ex)
{
Console.WriteLine($"Erreur lecture: {ex.Message}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Erreur: {ex}");
}
finally
{
foreach (var conn in connections)
{
conn.Dispose();
}
}
Console.WriteLine("Terminé. Appuyez sur une touche...");
Console.ReadKey();
// ← Retour explicite
return;
}
}
}
Hi, It seems like your…
Hi,
It seems like your concentrator doesn't allow multiple connections at the same time.
You need to create a client app that establishes the connection to the meter.
Then the client application reads meters behind the concentrator one at a time.
BR,
Mikko