diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 380a0ca..6ceed9f 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -4,7 +4,7 @@ on: push: branches: [ master ] pull_request: - branches: [ master ] + branches: [ master, tgb2 ] jobs: build: diff --git a/src/ism7config/Program.cs b/src/ism7config/Program.cs index 243a63d..b2643cd 100644 --- a/src/ism7config/Program.cs +++ b/src/ism7config/Program.cs @@ -59,7 +59,7 @@ static async Task Main(string[] args) var unitOfWork = new InMemoryDatabase(); var textService = new TextService(); - var nc = new NetworkConnector(unitOfWork, textService, new NetworkConnectorSettings{TcpClientConnectTimeoutMs = 1000}, new BusconfigPendingGatewaysSingleton()); + var nc = new NetworkConnector(unitOfWork, textService, new NetworkConnectorSettings{TcpClientConnectTimeoutMs = 60000}, new BusconfigPendingGatewaysSingleton()); var streamHandler = new XplatStreamHandler(); var gw = new GatewayBO diff --git a/src/ism7config/XplatStreamHandler.cs b/src/ism7config/XplatStreamHandler.cs index ccf10b7..b70022f 100644 --- a/src/ism7config/XplatStreamHandler.cs +++ b/src/ism7config/XplatStreamHandler.cs @@ -16,30 +16,38 @@ public XplatStreamHandler() } public async Task GetStream(TcpClient tcpClient, int port) { - var certificate = (X509Certificate)_loadCertMethodInfo.Invoke(new SslStreamHandler(), null); - var ssl = new SslStream(tcpClient.GetStream(), false, (a, b, c, d) => true); - - var sslOptions = new SslClientAuthenticationOptions - { - TargetHost = "ism7.server", - ClientCertificates = new X509Certificate2Collection(new X509Certificate2(certificate)), - }; - if (!OperatingSystem.IsWindows()) + try { - try + var certificate = (X509Certificate)_loadCertMethodInfo.Invoke(new SslStreamHandler(), null); + var ssl = new SslStream(tcpClient.GetStream(), false, (a, b, c, d) => true); + + var sslOptions = new SslClientAuthenticationOptions { - sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(new[] - { - TlsCipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256 - }); - } - catch (PlatformNotSupportedException) + TargetHost = "ism7.server", + ClientCertificates = new X509Certificate2Collection(new X509Certificate2(certificate)), + }; + if (!OperatingSystem.IsWindows()) { - //older linux or mac https://github.com/dotnet/runtime/issues/33649 + try + { + sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(new[] + { + TlsCipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256 + }); + } + catch (PlatformNotSupportedException) + { + //older linux or mac https://github.com/dotnet/runtime/issues/33649 + } } + using var cts = new CancellationTokenSource(60000); + await ssl.AuthenticateAsClientAsync(sslOptions, cts.Token); + return ssl; + } + catch (Exception ex) + { + Console.WriteLine(ex); + throw; } - using var cts = new CancellationTokenSource(5000); - await ssl.AuthenticateAsClientAsync(sslOptions, cts.Token); - return ssl; } } \ No newline at end of file diff --git a/src/ism7mqtt/HomeAssistant/HaDiscovery.cs b/src/ism7mqtt/HomeAssistant/HaDiscovery.cs index 5ec8194..f17bc90 100644 --- a/src/ism7mqtt/HomeAssistant/HaDiscovery.cs +++ b/src/ism7mqtt/HomeAssistant/HaDiscovery.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text.Json.Nodes; using System.Text.RegularExpressions; @@ -11,6 +12,8 @@ public class HaDiscovery { private readonly Ism7Config _config; + public bool EnableDebug { get; set; } + public HaDiscovery(Ism7Config config) { _config = config; @@ -168,9 +171,27 @@ private string GetHomeAssistantType(ParameterDescriptor descriptor) if (numeric.IsWritable) { if (numeric.MinValueCondition != null) - yield return("min", Double.Parse(numeric.MinValueCondition)); + { + if (Double.TryParse(numeric.MinValueCondition, NumberStyles.Number, CultureInfo.InvariantCulture, out var min)) + { + yield return("min", min); + } + else if (EnableDebug) + { + Console.WriteLine($"Cannot parse MinValueCondition '{numeric.MinValueCondition}' for PTID {descriptor.PTID}"); + } + } if (numeric.MaxValueCondition != null) - yield return ("max", Double.Parse(numeric.MaxValueCondition)); + { + if (Double.TryParse(numeric.MaxValueCondition, NumberStyles.Number, CultureInfo.InvariantCulture, out var max)) + { + yield return ("max", max); + } + else if (EnableDebug) + { + Console.WriteLine($"Cannot parse MaxValueCondition '{numeric.MaxValueCondition}' for PTID {descriptor.PTID}"); + } + } if (numeric.StepWidth != null) yield return ("step", numeric.StepWidth); } diff --git a/src/ism7mqtt/ISM7/Ism7Client.cs b/src/ism7mqtt/ISM7/Ism7Client.cs index 3811adb..412ac70 100644 --- a/src/ism7mqtt/ISM7/Ism7Client.cs +++ b/src/ism7mqtt/ISM7/Ism7Client.cs @@ -131,7 +131,7 @@ private async Task OnCommandAsync(List writeRequests, CancellationTok var request = new TelegramBundleReq { AbortOnError = true, - BundleId = NextBundleId(), + BundleId = "1099", GatewayId = "1", TelegramBundleType = TelegramBundleType.write, InfoWriteTelegrams = writeRequests @@ -276,9 +276,11 @@ private async Task OnPushResponseAsync(IResponse response, CancellationToken can private async Task LoadInitialValuesAsync(CancellationToken cancellationToken) { + var visibleDevices = new List(); foreach (var device in _devices.Values) { if (!_config.AddDevice(_ipAddress.ToString(), device.Ba)) continue; + visibleDevices.Add(device.Ba); var infoReads = _config.GetInfoReadForDevice(device.Ba).ToList(); var bundleId = NextBundleId(); _dispatcher.SubscribeOnce( @@ -306,6 +308,19 @@ await SendAsync(new TelegramBundleReq { await OnInitializationFinishedAsync(_config, cancellationToken); } + var bn = NextBundleId(); + await SendAsync(new TelegramBundleReq + { + AbortOnError = false, + BundleId = bn, + GatewayId = "1", + TelegramBundleType = TelegramBundleType.push, + EStRead = new TelegramBundleReq.ErrorStateRead + { + Seq = bn, + VisibleDeviceAdresses = String.Join(',', visibleDevices) + } + }, cancellationToken); } private async Task OnInitialValuesAsync(IResponse response, CancellationToken cancellationToken) diff --git a/src/ism7mqtt/ISM7/Ism7Config.cs b/src/ism7mqtt/ISM7/Ism7Config.cs index 8212c83..d145497 100644 --- a/src/ism7mqtt/ISM7/Ism7Config.cs +++ b/src/ism7mqtt/ISM7/Ism7Config.cs @@ -227,7 +227,7 @@ public IEnumerable GetWriteRequest(ReadOnlyMemory propertyPar foreach (var result in results) { result.BusAddress = WriteAddress; - result.Seq = ""; + result.Seq = "A;142"; yield return result; } } @@ -240,7 +240,7 @@ public IEnumerable GetWriteRequest(JsonObject data) foreach (var result in results) { result.BusAddress = WriteAddress; - result.Seq = ""; + result.Seq = "A;142"; yield return result; } } diff --git a/src/ism7mqtt/ISM7/Protocol/XmlPayload.cs b/src/ism7mqtt/ISM7/Protocol/XmlPayload.cs index c7e9974..7ba5f3c 100644 --- a/src/ism7mqtt/ISM7/Protocol/XmlPayload.cs +++ b/src/ism7mqtt/ISM7/Protocol/XmlPayload.cs @@ -13,16 +13,26 @@ public abstract class XmlPayload : IPayload public byte[] Serialize() { - using var sw = new StringWriter(); + using var sw = new Utf8StringWriter(); var xmlWriter = XmlWriter.Create(sw, new XmlWriterSettings {Indent = false}); var serializer = _serializers.GetOrAdd(GetType(), x => new XmlSerializer(x)); - serializer.Serialize(xmlWriter, this); + + //suppress xmlns:xsi and xmlns:xsd + XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); + ns.Add("",""); + + serializer.Serialize(xmlWriter, this, ns); sw.Flush(); var xml = sw.ToString(); return Encoding.UTF8.GetBytes(xml); } public abstract PayloadType Type { get; } + + class Utf8StringWriter : StringWriter + { + public override Encoding Encoding => Encoding.UTF8; + } } } \ No newline at end of file diff --git a/src/ism7mqtt/Program.cs b/src/ism7mqtt/Program.cs index e7b8355..b4265de 100644 --- a/src/ism7mqtt/Program.cs +++ b/src/ism7mqtt/Program.cs @@ -126,7 +126,7 @@ static async Task Main(string[] args) if (_discoveryId != null) { - client.OnInitializationFinishedAsync = (config, c) => PublishDiscoveryInfo(config, mqttClient, c); + client.OnInitializationFinishedAsync = (config, c) => PublishDiscoveryInfo(config, mqttClient, enableDebug, c); } await client.RunAsync(password, cts.Token); } @@ -168,9 +168,9 @@ private static int GetEnvInt32(string name, int defaultValue = default) return (int)parsed; } - private static async Task PublishDiscoveryInfo(Ism7Config config, IMqttClient mqttClient, CancellationToken cancellationToken) + private static async Task PublishDiscoveryInfo(Ism7Config config, IMqttClient mqttClient, bool debug, CancellationToken cancellationToken) { - var discovery = new HaDiscovery(config); + var discovery = new HaDiscovery(config) { EnableDebug = debug }; foreach (var message in discovery.GetDiscoveryInfo(_discoveryId)) { var data = JsonSerializer.Serialize(message.Content);