github net-daemon/netdaemon 0.8.1
Release 0.8.1

latest releases: 24.16.0, 24.12.0, 24.8.0...
3 years ago

Implement the Rx API

Implement the System.Reactive based APIs. This is an alternative implementation to @jvert suggestions (thanks alot for this great idéa).

Since this is a very different aproach a new BaseClass NetDaemonRxApp is provided that implements the Rx style. This is event based and not async/await. All calls post a message on a channel and async code takes care of the async stuff in the background.

More API features will be added coming releases to this API.

Check out my running production automations at showcasing the new API:
https://github.com/helto4real/hassio/tree/master/netdaemon/apps

Example of usage:

// Observable that get state changes 
StateChanges.Subscribe(t=> Log(t.New.State));

// Observable that get all state changes inkluding attributes 
StateAllChanges.Subscribe(t=> Log(t.New.State));

// IEnumerable<EntityState>
var allLights = States.Select(n => n.EntityId.StartsWith("light."));
// Gets single state
var state = State("light.my_light")?.State;

// No async, handled in background
CallService("light", "turn_on", new {entity_id = "light.my_light"});

// Entity now not fluent
// Action on single entity
Entity("light.my_light").TurnOn();
Entity("light.my_light").Toggle();
// Action on multiple entities
Entities("light.my_light", "light.my_light").Toggle();
// Or lambda
Entities(n => n.EntityId.StartsWith("light.").Toggle();

// Merging observables <3
Entities(
    "binary_sensor.tomas_rum_pir",
    "binary_sensor.vardagsrum_pir")
    .StateChanges
    .Subscribe(e =>
    {
        Log("{entity}: {state}({oldstate}, {lastchanged})", e.New.EntityId, e.New.State, e.Old.State, e.New.LastChanged);
    });

// Merging observables all changes including attributes <3
Entities(
    "binary_sensor.tomas_rum_pir",
    "binary_sensor.vardagsrum_pir")
    .StateAllChanges
    .Subscribe(e =>
    {
        Log("{entity}: {state}({oldstate}, {lastchanged})", e.New.EntityId, e.New.State, e.Old.State, e.New.LastChanged);
    });

// Set state
SetState("sensor.thesensor", "on", new {attributex="cool"});
// Set state selecting with Entity Selector
Entity("sensor.x", "sensor.y").SetState("on");

// Merging of entity results

// Schedulers
RunEvery(TimeSpan.FromMinutes(1)).Subscribe(....);

RunDaily("12:00:00").Subscribe(...);

// Events
EventChanges
     .Subscribe(f =>
      {
            Log("event: {domain}.{event} - {data}", f?.Domain??"none", f.Event, f?.Data);
       });

// All events including attribute changes
EventAllChanges
     .Subscribe(f =>
      {
            Log("event: {domain}.{event} - {data}", f?.Domain??"none", f.Event, f?.Data);
       });

Additional information

In order to make application lifecycle easier, all eventlisteners and state handlers are tied to each app-instance. This makes it way more easy to disable individual apps in runtime plus manage lifecykle in the Rx stuff too. More refactorings to come to make it easier for future changes

Don't miss a new netdaemon release

NewReleases is sending notifications on new releases.