Skip to content

Commit

Permalink
Merge pull request #15 from JonasMH/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
JonasMH authored Apr 12, 2023
2 parents d55a145 + 1b1ab44 commit c8f6c10
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 47 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.100
dotnet-version: 7.x
- name: Restore
run: dotnet restore
- name: Build
Expand Down Expand Up @@ -71,7 +71,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.100
dotnet-version: 7.x
- name: Create Release NuGet package
run: |
arrTag=(${GITHUB_REF//\// })
Expand Down
7 changes: 3 additions & 4 deletions src/ToMqttNet/DeviceTypes/MqttDefaultLightDiscoveryConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,14 @@ public class MqttDefaultLightDiscoveryConfig : MqttDiscoveryConfig
/// , default: OFF
///</summary>
[JsonProperty("payload_off")]
public string? PayloadOff { get; set; }
public object? PayloadOff { get; set; }

///<summary>
/// The payload that represents enabled state.
/// , default: ON
///</summary>
[JsonProperty("payload_on")]
public string? PayloadOn { get; set; }
public object? PayloadOn { get; set; }

///<summary>
/// The maximum QoS level of the state topic.
Expand Down Expand Up @@ -254,10 +254,9 @@ public class MqttDefaultLightDiscoveryConfig : MqttDiscoveryConfig

///<summary>
/// The schema to use. Must be default or omitted to select the default schema.
/// , default: default
///</summary>
[JsonProperty("schema")]
public string? Schema { get; set; }
public string? Schema { get; } = "basic";

///<summary>
/// The MQTT topic subscribed to receive state updates.
Expand Down
3 changes: 1 addition & 2 deletions src/ToMqttNet/DeviceTypes/MqttJsonLightDiscoveryConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,9 @@ public class MqttJsonLightDiscoveryConfig : MqttDiscoveryConfig

///<summary>
/// The schema to use. Must be json to select the JSON schema.
/// , default: default
///</summary>
[JsonProperty("schema")]
public string? Schema { get; set; }
public string? Schema { get; } = "json";

///<summary>
/// The MQTT topic subscribed to receive state updates.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,9 @@ public class MqttTemplateLightDiscoveryConfig : MqttDiscoveryConfig

///<summary>
/// The schema to use. Must be template to select the template schema.
/// , default: default
///</summary>
[JsonProperty("schema")]
public string? Schema { get; set; }
public string? Schema { get; } = "template";

///<summary>
/// Template to extract state from the state payload value.
Expand Down
5 changes: 3 additions & 2 deletions src/ToMqttNet/IMqttConnectionService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using MQTTnet;
using Newtonsoft.Json;
using MQTTnet.Client;
using MQTTnet.Packets;

namespace ToMqttNet
{
Expand All @@ -11,7 +12,7 @@ public interface IMqttConnectionService

MqttConnectionOptions MqttOptions { get; }

Task PublishAsync(params MqttApplicationMessage[] applicationMessages);
Task PublishAsync(MqttApplicationMessage applicationMessages);
Task SubscribeAsync(params MqttTopicFilter[] topics);
Task UnsubscribeAsync(params string[] topics);
}
Expand Down
9 changes: 8 additions & 1 deletion src/ToMqttNet/MqttConnectionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ public class MqttConnectionOptions
public string ClientId { get; set; } = null!;
[Required]
public string NodeId { get; set; } = null!;
public string Server { get; set; } = "mosquitto";
/// <summary>
/// If set will be used, even if <see cref="Server"/> is set
/// </summary>
public string? BrokerUrl { get; set; }
/// <summary>
/// If <see cref="BrokerUrl"/> is set, it will be used instead
/// </summary>
public string? Server { get; set; } = "mosquitto";
public int Port { get; set; } = 1883;
}
}
53 changes: 29 additions & 24 deletions src/ToMqttNet/MqttConnectionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
using Microsoft.Extensions.Options;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Packets;

namespace ToMqttNet
{
Expand All @@ -30,57 +30,62 @@ public MqttConnectionService(

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var options = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
.WithClientOptions(new MqttClientOptionsBuilder()
var clientOptionsBuilder = new MqttClientOptionsBuilder()
.WithClientId(MqttOptions.ClientId + "-" + _instanceId)
.WithTcpServer(MqttOptions.Server, MqttOptions.Port)
.WithWillMessage(
new MqttApplicationMessageBuilder()
.WithPayload("0")
.WithTopic($"{MqttOptions.NodeId}/connected")
.WithRetainFlag()
.Build()
)
.Build()
)
.Build();
.WithWillPayload("0")
.WithWillTopic($"{MqttOptions.NodeId}/connected")
.WithWillRetain();

if(!string.IsNullOrWhiteSpace(MqttOptions.BrokerUrl)) {
clientOptionsBuilder = clientOptionsBuilder.WithConnectionUri(MqttOptions.BrokerUrl);
} else {
clientOptionsBuilder = clientOptionsBuilder.WithTcpServer(MqttOptions.Server, MqttOptions.Port);
}

var clientOptions = clientOptionsBuilder;


var optionsBuilder = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
.WithClientOptions(clientOptions);

var options = optionsBuilder.Build();

_mqttClient = new MqttFactory()
.CreateManagedMqttClient();

_mqttClient.UseConnectedHandler(async (evnt) =>
_mqttClient.ConnectedAsync += async (evnt) =>
{
_logger.LogInformation("Connected to mqtt: {reason}", evnt.ConnectResult.ReasonString);

await _mqttClient.PublishAsync(
await _mqttClient.EnqueueAsync(
new MqttApplicationMessageBuilder()
.WithPayload("2")
.WithTopic($"{MqttOptions.NodeId}/connected")
.WithRetainFlag()
.Build());

OnConnect?.Invoke(this, new EventArgs());
});
};

_mqttClient.UseDisconnectedHandler((evnt) =>
_mqttClient.DisconnectedAsync += async (evnt) =>
{
_logger.LogInformation(evnt.Exception, "Disconnected from mqtt: {reason}", evnt.Reason);
OnDisconnect?.Invoke(this, new EventArgs());
});
};

_mqttClient.UseApplicationMessageReceivedHandler((evnt) =>
_mqttClient.ApplicationMessageReceivedAsync += async (evnt) =>
{
_logger.LogTrace("{topic}: {message}", evnt.ApplicationMessage.Topic, evnt.ApplicationMessage.ConvertPayloadToString());
OnApplicationMessageReceived?.Invoke(this, evnt);
});
};

await _mqttClient.StartAsync(options);
}

public Task PublishAsync(params MqttApplicationMessage[] applicationMessages)
public Task PublishAsync(MqttApplicationMessage applicationMessages)
{
return _mqttClient!.PublishAsync(applicationMessages);
return _mqttClient!.EnqueueAsync(applicationMessages);
}

public Task SubscribeAsync(params MqttTopicFilter[] topics)
Expand Down
18 changes: 9 additions & 9 deletions src/ToMqttNet/ToMqttNet.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -14,13 +14,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="MQTTnet" Version="3.1.1" />
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="MQTTnet" Version="4.1.4.563" />
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="4.1.4.563" />
</ItemGroup>
</Project>
66 changes: 66 additions & 0 deletions test/ToMqttNet.Test.Unit/MqttDefaultLightDiscoveryConfigTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace ToMqttNet.Test.Unit
{

public class MqttDefaultLightDiscoveryConfigTests
{
[Fact]
public void ToJson_SchemaIsBasic()
{
// Arrange
var sut = new MqttDefaultLightDiscoveryConfig()
{

};

// Act
var result = (JObject)JsonConvert.DeserializeObject(sut.ToJson())!;

// Assert
Assert.Equal("basic", result["schema"]!.ToString());
// The documentation says it should be null or default - but in reality setting this to default makes it fail, so we just force it to basic
}

[Fact]
public void ToJson_PayloadCanBeBoolean()
{
// Arrange
var sut = new MqttDefaultLightDiscoveryConfig()
{
PayloadOn = true
};

// Act
var result = (JObject)JsonConvert.DeserializeObject(sut.ToJson())!;

// Assert
Assert.True(result["payload_on"]!.Value<bool>());
// The documentation says it should be null or default - but in reality setting this to default makes it fail, so we just force it to basic
}

[Fact]
public void ToJson_PayloadCanBeString()
{
// Arrange
var sut = new MqttDefaultLightDiscoveryConfig()
{
PayloadOn = "someString"
};

// Act
var result = (JObject)JsonConvert.DeserializeObject(sut.ToJson())!;

// Assert
Assert.Equal("someString", result["payload_on"]!.Value<string>());
// The documentation says it should be null or default - but in reality setting this to default makes it fail, so we just force it to basic
}
}
}
25 changes: 25 additions & 0 deletions test/ToMqttNet.Test.Unit/MqttJsonLightDiscoveryConfigTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using Xunit;

namespace ToMqttNet.Test.Unit
{
public class MqttJsonLightDiscoveryConfigTests
{
[Fact]
public void ToJson_SchemaIsBasic()
{
// Arrange
var sut = new MqttJsonLightDiscoveryConfig()
{

};

// Act
var result = (JObject)JsonConvert.DeserializeObject(sut.ToJson())!;

// Assert
Assert.Equal("json", result["schema"]!.ToString());
}
}
}
25 changes: 25 additions & 0 deletions test/ToMqttNet.Test.Unit/MqttTemplateLightDiscoveryConfigTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using Xunit;

namespace ToMqttNet.Test.Unit
{
public class MqttTemplateLightDiscoveryConfigTests
{
[Fact]
public void ToJson_SchemaIsBasic()
{
// Arrange
var sut = new MqttTemplateLightDiscoveryConfig()
{

};

// Act
var result = (JObject)JsonConvert.DeserializeObject(sut.ToJson())!;

// Assert
Assert.Equal("template", result["schema"]!.ToString());
}
}
}
2 changes: 1 addition & 1 deletion test/ToMqttNet.Test.Unit/ToMqttNet.Test.Unit.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
Expand Down

0 comments on commit c8f6c10

Please sign in to comment.