DevJasper.NetDaemon.Extensions.Observables
0.1.0
DevJasper.NetDaemon.Extensions.Observables 0.1.1
Additional DetailsBoth LimitTrueDuration and WhenTrueFor handle the remaining time correctly. This is fixed in version 0.1.1.
dotnet add package DevJasper.NetDaemon.Extensions.Observables --version 0.1.0
NuGet\Install-Package DevJasper.NetDaemon.Extensions.Observables -Version 0.1.0
<PackageReference Include="DevJasper.NetDaemon.Extensions.Observables" Version="0.1.0" />
<PackageVersion Include="DevJasper.NetDaemon.Extensions.Observables" Version="0.1.0" />
<PackageReference Include="DevJasper.NetDaemon.Extensions.Observables" />
paket add DevJasper.NetDaemon.Extensions.Observables --version 0.1.0
#r "nuget: DevJasper.NetDaemon.Extensions.Observables, 0.1.0"
#:package DevJasper.NetDaemon.Extensions.Observables@0.1.0
#addin nuget:?package=DevJasper.NetDaemon.Extensions.Observables&version=0.1.0
#tool nuget:?package=DevJasper.NetDaemon.Extensions.Observables&version=0.1.0
NetDaemon.Extensions.Observables
Collection of extension methods meant to enhance NetDaemon entities with stateful and boolean observables allowing for more robust implementations and a more intuitive coding experience.
For more information on NetDaemon, click here.
Example Usage
public Example(
SunEntities sunEntities,
CoverEntities coverEntities)
{
const int curtainCloseSunElevation = 1;
var sunIsDown = sunEntities.Sun
.ToBooleanObservable(e => e.Attributes?.Elevation <= curtainCloseSunElevation);
sunIsDown.SubscribeTrueFalse(
() =>
{
coverEntities.LivingRoomFrontWindowCurtain.CloseCover();
coverEntities.LivingRoomBackWindowCurtain.CloseCover();
},
() =>
{
coverEntities.LivingRoomFrontWindowCurtain.OpenCover();
coverEntities.LivingRoomBackWindowCurtain.OpenCover();
});
}
Breakdown:
sunEntities.Sun.ToBooleanObservable(e => e.Attributes?.Elevation <= curtainCloseSunElevation);
Create a stateful IObservable<bool> from the sun entity Sun which emits true when Elevation is smaller than curtainCloseSunElevation, false otherwise. Stateful in this context means that the observable will immediately emit the current value returned from the predicate when an observer is subscribed.
sunIsDown.SubscribeTrueFalse(
() =>
{
coverEntities.LivingRoomFrontWindowCurtain.CloseCover();
coverEntities.LivingRoomBackWindowCurtain.CloseCover();
},
() =>
{
coverEntities.LivingRoomFrontWindowCurtain.OpenCover();
coverEntities.LivingRoomBackWindowCurtain.OpenCover();
});
SubscribeTrueFalse is an extension method on IObservable<bool> that assigns an Action for when true is emitted as well as when false is emitted.
This implementation will immediately open or close the covers depending on the initial result of the predicate as well as update whenever the result of the predicate changes.
Stateful
As an addition to the StateChanges and StateAllChanges methods provided by NetDaemon, this library provides the methods Stateful and StatefulAll. The observable resulting from these methods will emit the current state of the entity upon subscribing to the observable. This allows a single subscription for both initial state and state changes.
Example
var frontWindowCurtainOpen = coverEntities.LivingRoomFrontWindowCurtain.ToOpenClosedObservable();
frontWindowCurtainOpen.SubscribeTrue(() => lightEntities.LivingRoomLights.TurnOff());
When starting this automation, the living room lights will immediately turn off if the front window curtain is open. It will also turn off every time the front window curtain is opened after that.
Boolean Observables
This library also contains a set of extension methods to convert entities to implementations of IObservable<bool>. If no predicate is provided, the On state is mapped to true, the Off state is mapped to false.
The usage of ToBooleanObservable (or one of the aliases ToOnOffObservable or ToOpenClosedObservable) on an entity will use StateChanges (or StateAllChanges when a predicate is provided) to result in a stateful IObservable<bool>.
In case a stateful observable is not desired, the method ToChangesOnlyBooleanObservable can be used.
The use of stateful IObservable<bool> implementations enables the use of logic operators and scheduling extensions provided by the Reactive.Boolean library. This allows for improved readability of implementations.
For a more detailed documentation on extension methods for IObservable<bool>, check out the documentation for Reactive.Boolean here.
Example
The following example shows the usage of boolean (Not, Or and And) and scheduling (LimitTrueDuration) logic to write a complex automation that is still easy to understand and will trigger on startup.
var noOneAsleep = inputBooleanEntities.JasperAsleep.ToBooleanObservable()
.Or(inputBooleanEntities.AnonAsleep.ToBooleanObservable()).Not();
var closetDoorOpenShorterThanOneMin = binarySensorEntities.BedroomClosetDoorSensorContact
.ToOpenClosedObservable().LimitTrueDuration(TimeSpan.FromMinutes(5), scheduler);
noOneAsleep.And(closetDoorOpenShorterThanOneMin).SubscribeTrueFalse(
() => lightEntities.ClosetLight.TurnOn(),
() => lightEntities.ClosetLight.TurnOff());
Note that even though scheduling is mostly handled by the Reactive.Boolean library, knowledge of the Entity does improve some scheduling methods. In the cases of WhenTrueFor and LimitTrueDuration both LastChanged and the passing of time are used to evaluate whether a true is emitted.
Unavailability of entities
This library also implements the utility method RepeatWhenEntitiesBecomeAvailable<T>. This method can be called on a IObservable<T> to repeat a value when one of the provided entities become available.
Example
The following example will re-apply the correct state as soon as the plug becomes available (is plugged in).
const int nightTimeSunElevation = 0;
var nightTime = sunEntities.Sun
.ToBooleanObservable(e => e.Attributes?.Elevation <= nightTimeSunElevation);
nightTime
.RepeatWhenEntitiesBecomeAvailable(switchEntities.LivingRoomChristmasTreeLights)
.SubscribeTrueFalse(
() => switchEntities.LivingRoomChristmasTreeLights.TurnOn(),
() => switchEntities.LivingRoomChristmasTreeLights.TurnOff());
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net8.0
- NetDaemon.HassModel (>= 24.43.0)
- Reactive.Boolean (>= 0.2.1)
-
net9.0
- NetDaemon.HassModel (>= 24.43.0)
- Reactive.Boolean (>= 0.2.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 |
|---|