Pacem.Domotics.OpenWebNet 0.10.17

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Pacem.Domotics.OpenWebNet --version 0.10.17
                    
NuGet\Install-Package Pacem.Domotics.OpenWebNet -Version 0.10.17
                    
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="Pacem.Domotics.OpenWebNet" Version="0.10.17" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Pacem.Domotics.OpenWebNet" Version="0.10.17" />
                    
Directory.Packages.props
<PackageReference Include="Pacem.Domotics.OpenWebNet" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Pacem.Domotics.OpenWebNet --version 0.10.17
                    
#r "nuget: Pacem.Domotics.OpenWebNet, 0.10.17"
                    
#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.
#:package Pacem.Domotics.OpenWebNet@0.10.17
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Pacem.Domotics.OpenWebNet&version=0.10.17
                    
Install as a Cake Addin
#tool nuget:?package=Pacem.Domotics.OpenWebNet&version=0.10.17
                    
Install as a Cake Tool

Pacem.Domotics.OpenWebNet

An OpenWebNet (BTicino / Legrand MyHOME) client: connect to a gateway, drive lights, dimmers, door locks and energy meters, and receive bus events as they happen.

Built on Pacem.Extensions.Sockets, so the link to the gateway survives reboots, cable pulls and gateways that vanish for an afternoon.

Install

dotnet add package Pacem.Domotics.OpenWebNet

Targets net10.0.

Quick start

services.AddPacemOpenWebNet();
var gateways = provider.GetRequiredService<IOpenWebNetGatewayFactory>();
var devices  = provider.GetRequiredService<IOpenWebNetDeviceFactory>();

using var gateway = gateways.CreateGateway("172.24.0.100", Gateway.DefaultBTicinoPort);

gateway.Events.OnOpenWebNetResponseAsync = ctx =>
{
    if (ctx.Response is LightingResponse light)
    {
        Console.WriteLine($"light {light.Where} -> {light.LightStatus} ({light.Intensity:P0})");
    }
    return Task.CompletedTask;
};

await gateway.ConnectAsync();

var kitchen = (Light)devices.CreateOpenWebNetDevice(gateway, KnownDeviceType.Light, where: 11);
await kitchen.RequestStatusAsync();
await kitchen.SwitchOnAsync();

How it is wired

A Gateway holds two sockets to the same endpoint, as the protocol expects: a command channel for requests and a listen channel for spontaneous bus events. Both keep themselves alive and reconnect independently.

Devices are created against a gateway and register themselves for the messages addressed to them. Incoming frames are routed by (WHO, WHERE) — so a light and an energy meter may share an address without stealing each other's messages.

your code ──► IOpenWebNetDeviceFactory ──► Light / ConsumptionTracker / DoorEntry
                                              │
                                              ▼
                                          Gateway ──► command socket ──► BTicino gateway
                                                 ◄── listen  socket ◄──

Connecting is non-blocking

ConnectAsync() does not throw or hang when the gateway is unreachable — the underlying connections retry in the background. Check IsSenderConnected / IsReceiverConnected:

await gateway.ConnectAsync();
if (!gateway.IsSenderConnected)
{
    // still coming up; commands will be dropped with a logged error until it is
}

Devices

KnownDeviceType Type Capabilities
Light Light on / off / toggle / timed on / blink
Dimmer Light (IsDimmable) the above, plus DimToAsync
ConsumptionTracker ConsumptionTracker instantaneous, total, daily, monthly
Door DoorEntry UnlockAsync
var lamp = (Light)devices.CreateOpenWebNetDevice(gateway, KnownDeviceType.Dimmer, 12);
await lamp.DimToAsync(0.4);          // 40%
await lamp.BlinkAsync(1.5);          // 1.5s

var meter = (ConsumptionTracker)devices.CreateOpenWebNetDevice(gateway, KnownDeviceType.ConsumptionTracker, 7);
await meter.RequestCurrentAsync();
await meter.RequestMonthlyAsync(2026, 9);

var door = (DoorEntry)devices.CreateOpenWebNetDevice(gateway, KnownDeviceType.Door, 0);
await door.UnlockAsync();

Gateways and devices are cached per endpoint and per (gateway, type, where), so asking twice gives you the same instance.

Device state (Light.Status, Light.Intensity, …) reflects the last message received, not a live query — call RequestStatusAsync() to refresh it. Note that SwitchOnAsync / SwitchOffAsync short-circuit when the cached state already matches.

Events

Set handlers on gateway.Events:

Handler Fires on
OnOpenWebNetResponseAsync Every parsed frame from either channel
OnOpenWebNetRequestAsync Every request sent
OnConnectedAsync / OnDisconnectedAsync / OnCloseAsync Channel lifecycle
OnErrorAsync Transport failures

Each carries the CommunicationMode (Listen or Command) of the channel it came from. Handlers run on the receive pump — keep them quick.

Parsing frames yourself

OpenWebNetResponse? response = OpenWebNetResponse.Parse("*1*1*11##");
IEnumerable<OpenWebNetResponse> many = OpenWebNetResponse.Extract("*1*1*11##*1*0*12##");

Parse takes one complete frame and returns null for frames whose WHO this library does not model. Extract splits a buffer and discards a trailing incomplete frame — the Gateway itself uses a stateful reader instead, so messages split across TCP reads are re-assembled rather than lost.

Modelled today: lighting (WHO 1), energy (WHO 18) and acknowledgements. Other WHOs reach OnOpenWebNetResponseAsync as null and are logged at trace level.

A note on WHO values

OpenWebNetWhoTable gathers the WHO constants. Two caveats worth carrying:

  • Devices answer on the WHO given by their KnownDeviceType, which is not always the WHO their commands go out on — door entry is the live example (DoorEntry = 6 vs VideoDoorEntry = 7). Gateway generations differ here.
  • Routing is by (WHO, WHERE), so an incorrect WHO does not produce an error — it silently starves the device of its own messages. Confirm against your hardware rather than against the published tables.

License

Apache 2.0.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
0.10.18-pascal 0 9/21/2026
0.10.17 37 9/18/2026
0.10.17-foucault 45 9/18/2026
0.10.16 46 9/16/2026
0.10.16-hamilton 66 9/14/2026
0.10.16-gauss 67 9/14/2026
0.10.16-faraday 87 9/9/2026
0.10.15 86 9/7/2026