ZWaveSerialApi.Devices 1.1.1

dotnet add package ZWaveSerialApi.Devices --version 1.1.1
NuGet\Install-Package ZWaveSerialApi.Devices -Version 1.1.1
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="ZWaveSerialApi.Devices" Version="1.1.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ZWaveSerialApi.Devices --version 1.1.1
#r "nuget: ZWaveSerialApi.Devices, 1.1.1"
#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 ZWaveSerialApi.Devices as a Cake Addin
#addin nuget:?package=ZWaveSerialApi.Devices&version=1.1.1

// Install ZWaveSerialApi.Devices as a Cake Tool
#tool nuget:?package=ZWaveSerialApi.Devices&version=1.1.1

C# Z-Wave Serial API

This API is for C#/.NET developers who want to create their own home automation tool using a Z-Wave USB stick, such as the Aeotec Z-Stick 7.

Since this API doesn't support Z-Wave protocol security (S0 or S2) it should not be used for burglar alarms, door locks, etc.

Requirements

  • .NET 5.0

Examples

Getting started

using var network = new ZWaveNetwork("COM3");
await network.ConnectAsync();

var multiSensor = network.GetDevices<AeotecMultiSensor6>().First();

// Register for unsolicited motion notifications
multiSensor.MotionDetected += (_, _) =>
{
    /* Motion detection started */
};
multiSensor.MotionIdle += (_, _) =>
{
    /* Motion detection stopped */
};

// Get sensor values
var temperature = await multiSensor.GetTemperatureAsync(TemperatureScale.Celsius);
Console.WriteLine($"Temperature: {temperature.Value}{temperature.Unit}");

var humidity = await multiSensor.GetHumidityAsync(HumidityScale.Percentage);
Console.WriteLine($"Humidity: {humidity.Value}{humidity.Unit}");

Adding (including) devices

using var network = new ZWaveNetwork("COM3");
await network.ConnectAsync();

// Add/include device
var (success, device) = await network.AddDeviceAsync();

// Add/include device (optional callback when controller is ready)
(success, device) = await network.AddDeviceAsync(
                        () => Console.WriteLine("Initiate inclusion on device (ie. press button according to manual."));

// Add/include device (optional initialization for wake-up devices)
(success, device) = await network.AddDeviceAsync(
                        wakeUpInitializationFunc: async wakeUpDevice =>
                        {
                            const int IntervalHours = 2;
                            var wakeUpCapabilities = await wakeUpDevice.GetWakeUpIntervalCapabilitiesAsync();
                            var intervalSeconds = TimeSpan.FromHours(IntervalHours).TotalSeconds
                                                  - TimeSpan.FromHours(IntervalHours).TotalSeconds
                                                  % wakeUpCapabilities.IntervalStep.TotalSeconds;
                            await wakeUpDevice.SetWakeUpIntervalAsync(TimeSpan.FromHours(intervalSeconds));
                        });

// Add/include device (optional cancellation tokens)
// The cancellation token will stop the adding process immediately. This may leave the network in an unusable state which requires a reconnect.
// The abort token will stop the adding process nicely until a device is found. Once a device has been found then the token will do nothing.
var cancellationToken = new CancellationTokenSource().Token;
var abortRequestedToken = new CancellationTokenSource().Token;
(success, device) = await network.AddDeviceAsync(cancellationToken: cancellationToken, abortRequestedToken: abortRequestedToken);

Removing (excluding) devices

using var network = new ZWaveNetwork("COM3");
await network.ConnectAsync();

// Remove/exclude device
await network.RemoveDeviceAsync();

// Remove/exclude device (optional callback when controller is ready)
await network.RemoveDeviceAsync(() => Console.WriteLine("Initiate exclusion on device (ie. press button according to manual."));

// Remove/exclude device (optional cancellation tokens)
// The cancellation token will stop the removal process immediately. This may leave the network in an unusable state which requires a reconnect.
// The abort token will stop the removal process nicely until a device is found. Once a device has been found then the token will do nothing.
var cancellationToken = new CancellationTokenSource().Token;
var abortRequestedToken = new CancellationTokenSource().Token;
await network.RemoveDeviceAsync(cancellationToken: cancellationToken, abortRequestedToken: abortRequestedToken);

Network settings persistance

When connecting, the API will attempt to query all unknown devices. Devices that are sleeping will be added when they wake up.

Cut down startup time by persisting the network information.

using var network = new ZWaveNetwork("COM3");
await network.LoadAsync("ZWaveNetwork.json");
await network.ConnectAsync();

// ... program logic ...

await network.SaveAsync("ZWaveNetwork.json");

Wake up processing

Make calls to battery operated devices while they are awake, either every time or just once.

var multiSensor = network.GetDevices<AeotecMultiSensor6>().First();
multiSensor.WakeUpNotification += async (_, _) =>
{
    // ... processing every time device wakes up ...
};

async Task MultiSensorSetupAsync(object? sender, EventArgs eventArgs)
{
    // ... one-time setup of device when it wakes up ...

    multiSensor.WakeUpNotification -= MultiSensorSetupAsync;
}

multiSensor.WakeUpNotification += MultiSensorSetupAsync;

Device parameters

Read and write device configuration parameters.

var multiSensor = network.GetDevices<AeotecMultiSensor6>().First();

// Get current value
var timeout = await multiSensor.Parameters.MotionTimeout.GetAsync();
Console.WriteLine($"MotionTimeout: {timeout.TotalSeconds}");

// Set new value
await multiSensor.Parameters.MotionTimeout.SetAsync(TimeSpan.FromMinutes(1));

Using device location

When using multiple devices of the same type, it helps to assign a location to each device.

// Set location
var unknownMultiSensor = network.GetDevices<AeotecMultiSensor6>().First();
unknownMultiSensor.Location = "Kitchen";

// Get by location
var kitchenMultiSensor = network.GetDevice<AeotecMultiSensor6>("Kitchen");

Converting unsolicited values

Units for unsolicited values are defined in the configuration of each device. If there is a need to use alternative units they can be converted manually.

static void OutputBothTemperatureUnits(MultilevelSensorReport temperature)
{
    switch (temperature.Scale)
    {
        case TemperatureScale.Celsius:
            var farenheitValue = temperature.Value * 9 / 5 + 32;
            var (farenheitUnit, _) = AttributeHelper.GetUnit(TemperatureScale.Fahrenheit);
            Console.WriteLine($"Temperature = {temperature.Value}{temperature.Unit} / {farenheitValue}{farenheitUnit}");
            break;
        case TemperatureScale.Fahrenheit:
            var celsiusValue = (temperature.Value - 32) * 5 / 9;
            var (celsiusUnit, _) = AttributeHelper.GetUnit(TemperatureScale.Fahrenheit);
            Console.WriteLine($"Temperature = {celsiusValue}{celsiusUnit} / {temperature.Value}{temperature.Unit}");
            break;
    }
}

var aerq = network.GetDevices<AeotecAerqSensor>().First();
aerq.TemperatureReport += (_, eventArgs) => OutputBothTemperatureUnits(eventArgs.Report);

Custom device types

Create an issue for missing devices. Until they are part of the API, you can create a custom type. See CustomMultilevelSensor.cs source code and below example for how it's used.

using var network = new ZWaveNetwork("COM3");

// Get the device type of the unsupported device, either
// 1) Input the data manually, eg.:
//    var customDeviceType = new DeviceType(0x0086, 0x0002, 0x0064);
// *OR*
// 2) Get the data from a device already on the network, eg.:
var customDeviceType = network.GetUnsupportedDeviceTypes().First();

network.RegisterCustomDeviceType(customDeviceType, (client, deviceState) => new CustomMultilevelSensor(client, deviceState));

await network.ConnectAsync();

var multiSensor = network.GetDevices<CustomMultilevelSensor>().First();
var temperature = await multiSensor.GetTemperatureAsync(TemperatureScale.Celsius);

Features not supported

  • Z-Wave security (ie. S0 and S2 classed communication with nodes)
  • MultiChannel/MultiCast
  • Association groups (device signalling other device, bypassing controller)
  • Scenes
Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  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. 
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
1.1.1 368 11/9/2021
1.1.0 300 11/8/2021
1.0.0 298 11/6/2021