-
-
Notifications
You must be signed in to change notification settings - Fork 80
Initial commit of MQTT entity management framework. #656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial commit of MQTT entity management framework. #656
Conversation
Addable extension method `AddMqttExtensions()`, rough entity creation through `EntityUpdater` (which is probably a poor name) that needs more strongly-typed.
| public static IServiceCollection AddMqttExtensions(this IServiceCollection services) | ||
| { | ||
| services.AddSingleton<IMqttFactory, MqttFactory>(); | ||
| services.AddScoped<IEntityUpdater, EntityUpdater>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scoped is only usefull if you have state in tje class that should be scoped (per app in case of ND) I think thats not the case here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern is the connection to mqtt, which times out after 10 seconds.
But actually... I remake the connection each time when a message is called, so that's probably not an issue.
OK - will update - thanks
|
@skotl I will add you to the dev team here. You can push to branch here your self and make it easier for you guys to collaborate |
|
Changed DI scope to Singleton for the local services, changed target branch to mqtt_extensions. |
| _logger = logger; | ||
| _mqttFactory = mqttFactory; | ||
|
|
||
| _mqttConfig = configuration.GetSection("Mqtt") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should use the options framework instead here.
|
|
||
| internal class MqttConfiguration | ||
| { | ||
| public string? Host { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these properties really nullable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not - I'll update - thanks :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can probably use a record here with a primary constructor and have the properties auto generated. That way you can make then non nullabe without getting warnings. Username and password might actually be optional
|
|
||
| public async Task SendMessageAsync(string topic, string payload) | ||
| { | ||
| using (var mqttClient = _mqttFactory.CreateMqttClient()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe cache this client in a field so it is not recreated each time and then dispose in Dispose if this class.
| { | ||
| services.AddSingleton<IMqttFactory, MqttFactory>(); | ||
| services.AddSingleton<IEntityUpdater, EntityUpdater>(); | ||
| services.AddSingleton<IMessageSender, MessageSender>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The MessageSender does not have any state so it does not have to be a singleton. I read its recimended to use transient in those cases (creating a new instance is relatively cheap)
helto4real
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am ok for this to be merged to the feature branch so @eugeneniemand and @skotl can work on it. I save my comments to the real PR. You can use these comments as guidance for your work. Thanks for the contribution!
| /// Adds scheduling capabilities through dependency injection | ||
| /// </summary> | ||
| /// <param name="services">Provided service collection</param> | ||
| public static IServiceCollection AddMqttExtensions(this IServiceCollection services) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AddNetDaemonMqttEntityManagement or something like that. In the other extensions we hade NetDaemon name here
| name = name, device_class = deviceClass, state_topic = statePath, json_attributes_topic = attrsPath | ||
| }); | ||
|
|
||
| await _messageSender.SendMessageAsync( topicPath, payload); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a ConfigureAawait(false). Even if chances are slim this is used by a UI app we did this in the rest of assemblies
| @@ -0,0 +1,6 @@ | |||
| namespace NetDaemon.Extensions.MqttEntities; | |||
|
|
|||
| public interface IMessageSender | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this intended to be exposed to users or internal interface? If internal make it internal. If it is inteneded to exposed to users. I would think we can have one public API/interface being injected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - definitely should be internal!
|
|
||
| _logger.LogDebug($"Sending to {message.Topic}:\r\n {message.ConvertPayloadToString()}"); | ||
|
|
||
| var publishResult = await client.PublishAsync(message, CancellationToken.None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ConfigureAwait (same reason as before, consistency)
* Initial commit of MQTT entity management framework. (#656) * Initial commit of MQTT entity management framework. Addable extension method `AddMqttExtensions()`, rough entity creation through `EntityUpdater` (which is probably a poor name) that needs more strongly-typed. * DI scope update from PR comment * Added Update and Remove methods and resolved some of the comments for PR #656 * Changing names to be less generic * Moved to src/extensions, renamed folder and fixed warning * Added example app and fixed IOptions for mqtt config * Fix CI Build error * Add support for nuget and default host (#660) * Added Discovery prefix * MQTT connect and publish can throw exceptions as well as return error codes, so handle each case in a consistent manner by throwing a new MqttConnection or MqttPublish exception. Add try...catch to the test app so that we can see when exceptions are thrown in called methods. * 1. Add XML comments 2. Remove unused IConfiguration arg from MessageSender constructor * Resolving PR comments * Merged Skotl's code and fixed hard coded retain flag * Removing throw and fixed warning. Added comment for Delay * address PR comments * Internalising... Co-authored-by: Scott Leckie <scott.leckie@kwolo.com> Co-authored-by: Tomas Hellström <tomas.hellstrom@yahoo.se>
* Initial commit of MQTT entity management framework. (net-daemon#656) * Initial commit of MQTT entity management framework. Addable extension method `AddMqttExtensions()`, rough entity creation through `EntityUpdater` (which is probably a poor name) that needs more strongly-typed. * DI scope update from PR comment * Added Update and Remove methods and resolved some of the comments for PR net-daemon#656 * Changing names to be less generic * Moved to src/extensions, renamed folder and fixed warning * Added example app and fixed IOptions for mqtt config * Fix CI Build error * Add support for nuget and default host (net-daemon#660) * Added Discovery prefix * MQTT connect and publish can throw exceptions as well as return error codes, so handle each case in a consistent manner by throwing a new MqttConnection or MqttPublish exception. Add try...catch to the test app so that we can see when exceptions are thrown in called methods. * 1. Add XML comments 2. Remove unused IConfiguration arg from MessageSender constructor * Resolving PR comments * Merged Skotl's code and fixed hard coded retain flag * Removing throw and fixed warning. Added comment for Delay * address PR comments * Internalising... Co-authored-by: Scott Leckie <scott.leckie@kwolo.com> Co-authored-by: Tomas Hellström <tomas.hellstrom@yahoo.se>
Addable extension method
AddMqttExtensions()Rough entity creation through
EntityUpdater(which is probably a poor name) that needs more strongly-typed.Note that I can't push this to a branch on the netdaemon core, which I think it would be better to be in - if you want to create a new branch ("mqtt_extensions" or similar?) then I can update the PR to point to that instead.
That will also allow Eugene and I to collaborate around the branch without upsetting your work.
This has been tested manually within the context of the
Create entities from NDdiscord chat.Breaking change
Non-breaking change
Proposed change
New extension project called
NetDaemon.Extensions.MqttEntitiesthat adds a services extensionAddMqttExtensions()that can be called from program.csSample usage:
Requires additional config in
appSettings.json:Type of change
Additional information
Checklist
If user exposed functionality or configuration variables are added/changed: