A .NET Core framework for home automation with Hubitat Elevate.
If you're looking for the demos and slides from My House Runs .NET, they're on this branch.
The Puppet.Automation project contains a generic sample based on the logic I use for my pantry door. For more sample automations, see all the Puppet.Automation classes I've created for my house in this branch.
-
An event on one of your devices is triggered. Example: Your pantry door opens, triggering a contact sensor to send open.
-
The Puppet Executive process captures that event from Hubitat's websocket interface and raises it as a
System.Event
that can be handled in .NET Core code. -
The Puppet Executive passes event to the
AutomationFactory
. TheAutomationFactory
class instantiates the correct implementation ofIAutomation
based on various hints and returns it to the Executive. Example: The Executive asksAutomationFactory
for IAutomation objects that are interested in this event (based on code attributes, likeTriggerDeviceAttribute
). -
The Executive executes the
Handle()
method on eachIAutomation
object. The object can manipulate other devices via theHubitat
class, of which an instance can be passed in by the Executive. See the example later in this doc.
Either build the entire solution with Visual Studio or build the Puppet.Executive project at the command line by going to the project directory and running dotnet build
.
It's built-in to the Hubitat. Make sure you've turned it on and opted-in all your devices you want to access from Puppet.
Configure appsettings.json. At a shell prompt, switch to the Puppet.Executive folder and run dotnet run
.
It'll run fine on Windows, which is where I test it. For production I use a Raspberry Pi running Raspbian for my instance.
-
Publish Puppet.Executive with the following:
dotnet publish -r linux-arm
This will build a self-contained deployment, including the SDK, so you won't need to install the SDK on the RPi.
-
Using your file copy tool of choice, copy the contents, which you'll find several levels deep in the bin directory, to a location on your RPi. I chose
/home/pi/executive
. -
SSH to your Raspberry Pi. Give the executables permission to run. For example:
chmod 755 /home/pi/executive/Puppet.Executive
-
Test the application by running it manually. Run the Executive with
./Puppet.Executive
. Press Ctrl+C to end it after you're satisfied it works. -
Setup crontab on your Raspberry Pi to run the two apps in the background on startup. Run
crontab -e
and add the following line:@reboot cd /home/pi/executive && ./Puppet.Executive > /home/pi/executive.log
This will run the app at startup and pipe its output to a log file in the home directory.
-
Reboot.
sudo reboot
- Add a class to
Puppet.Automation
. Name it whatever you want. I like ending withAutomation
as a convention, but do whatever you like. - Make it implement
Puppet.Common.Automation.IAutomation
. - Give it a constructor that takes a single
Puppet.Common.Services.HomeAutomationPlatform
if you want it to be able to do stuff to other devices on your Hubitat. - Decorate it with attributes to indicate what events the automation is interested in, like
TriggerDeviceAttribute
. - Run it. If your attributes are correct, that automation should get picked up and executed asynchronously.
namespace Puppet.Automation
{
[TriggerDevice("Lock.FrontDoorDeadbolt", Capability.Lock)]
public class NotifyOnDoorUnlock : AutomationBase
{
public NotifyOnDoorUnlock(HomeAutomationPlatform hub, HubEvent evt) : base (hub,evt)
{
}
public override Task Handle(CancellationToken token)
{
if(_evt.value == "unlocked")
{
if(_evt.descriptionText.Contains("was unlocked by"))
{
Speaker[] speakers = new Speaker[]{
_hub.GetDeviceByName<Speaker>("Speaker.KitchenSpeaker") as Speaker,
_hub.GetDeviceByName<Speaker>("Speaker.WebhookNotifier") as Speaker
};
speakers.Speak($"{_evt.descriptionText}.");
}
}
return Task.CompletedTask;
}
}
}
I hope you like my work here. If you're having trouble, that's understandable - I wrote it for me, and sometimes that means that I don't think through usability stuff. Create an issue in this repo, or, better yet, send me a PR!
Lastly, please check out my social media presences!
- Twitch (I stream programming stuff)
- My Twitch Archive on YouTube
- Cam