Powergrid 1.0.0

dotnet add package Powergrid --version 1.0.0
NuGet\Install-Package Powergrid -Version 1.0.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Powergrid" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Powergrid --version 1.0.0
#r "nuget: Powergrid, 1.0.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Powergrid as a Cake Addin
#addin nuget:?package=Powergrid&version=1.0.0

// Install Powergrid as a Cake Tool
#tool nuget:?package=Powergrid&version=1.0.0

Icon

What is this?

Powergrid is a package you can use with your Blazor applications to have instant communication between all your clients (circuits). Can even work across multiple instances of the same or other applications using a message broker.

How can I use it?

  1. Install the Powergrid dependency from NuGet

Package manager:

Install-Package Powergrid

.NET CLI:

dotnet add package Powergrid
  1. Add it to your Startup.ConfigureServices method.

As of now, you can choose between AddMqttPowergrid and AddOffgridPowergrid

  • AddMqttPowergrid connects to a Mqtt broker for truly distributed messaging. An overload can be used to configure the Mqtt connection manually. By default it tries to connect to a passwordless Mqtt broker instance on localhost:1883. Configuring by taking advantage of the IConfigurator is also possible. Just need to register the keys to the Powergrid > Mqtt sections. Available keys are the ones in the MqttOptions class. In your appsettings.json file, for example, it could look something like:
{
    // [...]
    "Powergrid": {
        "Mqtt": {
            "Host": "localhost",
            "Port": 1883
            // [...]
        }
    }
}
  • AddOffgridPowergrid (yes, I know it's not the most ideal name. Couldn't think of anything better) works by just looping back sent messages to subscribed keys. Should work just like the other, just without the distributed part.

Let's just use the latter one for this example:

public void ConfigureServices(IServiceCollection services)
{
	// [...]
    services.AddOffgridPowergrid();
    // [...]
}
  1. If you wish to make your life a little bit easier, add the using statement to your _Imports.razor file:
@using Powergrid

Preparations done! Now it's time to use it

  1. On a component of your choice, start by injecting the IPowerpole class:
@inject IPowerpole _powerpole
  1. Subscribe to stuff your component would like to be notified about
await _powerpole.SubscribeAsync<MyCoolSerializableClass>("My unique key for this event type", e => 
	InvokeAsync(() =>
		{
		    _pageTitle = e.Value.Title
		    StateHasChanged();
		    return Task.CompletedTask;
		}));
  1. Throw some information at it. In the same component, another component, or even in a razor page/controller, you can use the IPowerpole too to publish stuff:
await _powerpole.PublishAsync("My unique key for this event type", new MyCoolSerializableClass{ Title = "My very cool message" });

Easy way to try it

If you wish to see an implementation, and test it yourself, a simple test app is included in the examples directory.

A Dockerfile and docker-compose.yml files are included to spin up 3 load balanced instances of the example app for you to test.

Some things to note:

  • Because the callback will be called externally, you need to call InvokeAsync to interact with your component.
  • After you're done updating information, you will need to call the StateHasChanged method
  • For the key and value, you can use any object. As long as they are serializable/deserializable to/from a string using Microsoft's System.Text.Json's library.
  • Because of this, the object you send will not have the same reference as the one you received. Obviously. It's meant to be distributed (applies even when using the AddOffgridPowergrid option to avoid different behaviors).
  • In case of the same app instance, if more than one component subscribes to the same key, the objects they will receive will be the same reference amongst them (grouped by the subscription with the same generic parameter TValue). So be careful if you want to change stuff in the object.

Basic concepts of the inner workings

This package consists of 3 main Interfaces:

  • IPowerline is the singleton responsible to be the bridge to any basic message broker. Every message that goes to and from the app instance passes through the IPowerline.
  • ISubstation is the singleton that stores all callbacks related to subscriptions. It receives messages from the IPowerline, parses them and relays the data back to the components. Also serializes the objets to pass through to the IPowerline.
  • IPowerpole is the scoped contract that lives just as long as the scope it was injected into (circuit, controller etc). It is responsible for exposing the basic functionality to relay to the ISubstation. One crucial job it does too is to notify the ISubstation when it gets disposed of, so cleanup, and possible automatic unsubscriptions can be arranged.

And of course, some disclaimers:

  • As you could probably tell, I'm not an electrical engineer. So, the analogies are most likely flawed. But I thought it'd be funny, so I did it anyway.
  • I'm also not a software engineer. No idea how stupid this is. Feel free to help me improve on this if you wish.
  • I have no idea how scalable this is. I don't have the means to stress test it, nor the knowledge to estimate. I think it'd do fairly well, but I don't have data to back it up. As the previous point stated, feedbacks are welcome!
  • Yes, the icon was made in 5 minutes on Inkscape.
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.1 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETCoreApp 3.1

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0 418 6/27/2021