Created
January 1, 2022 17:28
-
-
Save anaisbetts/50f1985a66426e7d239b88d0344872f2 to your computer and use it in GitHub Desktop.
Doorbell Automation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace HomeDotAnaisDotDev; | |
using System; | |
using System.Linq; | |
using System.Reactive.Disposables; | |
using System.Reactive.Linq; | |
using HomeAssistantGenerated; | |
using NetDaemon.Common; | |
using NetDaemon.HassModel.Common; | |
using ReactiveUI; | |
using Splat; | |
[NetDaemonApp] | |
public class AutomaticBuzzerHandler : ReactiveObject, IDisposable | |
{ | |
CompositeDisposable disp = new(); | |
public AutomaticBuzzerHandler(IHaContext haContext) | |
{ | |
void d(IDisposable disposable) { disp.Add(disposable); } | |
var home = new Entities(haContext); | |
var notify = new NotifyServices(haContext); | |
this.Log().Info("Starting up AutomaticBuzzerHandler"); | |
var shouldUnlockDoor = home.BinarySensor.Dingdong.BooleanForEntity() | |
.Where(x => { | |
// Only trigger on off => on | |
if (!x) return false; | |
// If no one is at home, bail | |
if (home.AlarmControlPanel.Alarmo.State != "disarmed" && | |
home.InputSelect.HomeAwayOverride.State != "Force Home") return false; | |
// If they jump on the buzzer, bail | |
if (home.Switch.DoorBuzzerSwitch.State != "off") return false; | |
// If it's night time, bail | |
var now = DateTime.Now; | |
if (now.Hour < 8 || now.Hour > 19) return false; | |
return true; | |
}); | |
// Re-poll locations as soon as someone presses a button | |
d(shouldUnlockDoor.Subscribe(x => { | |
notify.MobileAppAdelineSPhone("request_location_update"); | |
notify.MobileAppPixel3("request_location_update"); | |
notify.MobileAppSmG981u1("request_location_update"); | |
notify.MobileAppSmG991b("request_location_update"); | |
})); | |
// Wait a few seconds before unlocking the door | |
var prng = new Random(); | |
var doorWithDelay = shouldUnlockDoor | |
.Select(x => Observable.Return(x).Delay(TimeSpan.FromMilliseconds(prng.Next(1000, 2000)))) | |
.Switch(); | |
// Buzz the door | |
d(doorWithDelay.Subscribe(_ => { | |
//home.Switch.DoorBuzzerSwitch.TurnOn(); | |
this.Log().Warn("WOULDVE BUZZED DOOR!"); | |
notify.Slack("Experimental: Would've buzzed door!"); | |
})); | |
// Figure out if anyone has come home recently | |
var anyoneChangedHomeAway = Observable.Merge( | |
new[] { home.Person.Ani, home.Person.Adeline, home.Person.Effie, home.Person.Ulrike }.Select(x => x.StateChanges().Select(y => $"{x.EntityId}: {y.New?.State}")) | |
); | |
d(anyoneChangedHomeAway.Subscribe(x => { | |
notify.Slack("Experimental: " + x); | |
})); | |
// Whenever anyone comes home, for the next 10 minutes, allow the elevator | |
// to be called | |
d(anyoneChangedHomeAway | |
.Where(x => x == "home") | |
.Select(_ => { | |
this.Log().Info("Someone has come home, allowing elevator to be called"); | |
notify.Slack("Experimental: enabling elevator call code"); | |
// Whenever anyone presses the outer door button, for the next 2 minutes, | |
// any subsequent press will call the elevator | |
return doorWithDelay | |
.Decay(TimeSpan.FromSeconds(2 * 60), RxApp.TaskpoolScheduler) | |
.Delay(TimeSpan.FromSeconds(3), RxApp.TaskpoolScheduler) | |
.TakeUntil(Observable.Timer(TimeSpan.FromMinutes(10), RxApp.TaskpoolScheduler)); | |
}) | |
.Switch() | |
.Repeat() | |
.Subscribe(_ => { | |
//home.Switch.CallElevatorSwitch.TurnOn(); | |
this.Log().Warn("WOULDVE CALLED ELEVATOR"); | |
notify.Slack("Experimental: Would've called elevator!"); | |
})); | |
} | |
public void Dispose() | |
{ | |
disp.Dispose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment