public FrontDoorLockSmartThingsIntegration(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { var config = _hub.Configuration.GetSection("FrontDoorLock"); _endpoint = new Uri(config["SmartThingsIntegrationEndpoint"]); _authToken = config["SmartThingsToken"]; }
/// <summary> /// Figures out the appropriate implementation of IAutomation based on the data in the event and returns it. /// </summary> /// <param name="evt"></param> /// <param name="hub"></param> /// <returns>An IEnumerable<IAutomation> containing the automations to be run for this event.</returns> public static IEnumerable <IAutomation> GetAutomations(HubEvent evt, HomeAutomationPlatform hub) { /* * Get the types from the assembly * where the type implements IAutomation and * the type has trigger attributes * where the trigger attribute names a mapped device that matches the device that caused the event * and the attribute also names a Capability that matches the device that caused the event * and the count of the matching trigger attributes is greater than 0 */ IEnumerable <Type> typeCollection = Assembly.LoadFrom(_automationAssembly).GetTypes() .Where(t => typeof(IAutomation).IsAssignableFrom(t) && (t.GetCustomAttributes <TriggerDeviceAttribute>() .Where(a => hub.LookupDeviceId(a.DeviceMappedName) == evt.DeviceId && a.Capability.ToString().ToLower() == evt.Name)) .Count() > 0); foreach (Type automation in typeCollection) { var thing = Activator.CreateInstance(automation, new Object[] { hub, evt }); if (thing is IAutomation automationSource) { yield return(automationSource); } } }
public PantryLightAutomation(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { _pantryLight = _hub.GetDeviceByMappedName <SwitchRelay>("Switch.PantryLight") as SwitchRelay; _kitchenSpeaker = _hub.GetDeviceByMappedName <Speaker>("Speaker.KitchenSpeaker") as Speaker; }
private static void StartRelevantAutomationHandlers(HubEvent evt) { // Get a reference to the automation var automations = AutomationFactory.GetAutomations(evt, _hub); foreach (IAutomation automation in automations) { // If this automation is already running, cancel all running instances _taskManager.CancelRunningInstances(automation.GetType(), evt.DeviceId); // Start a task to handle the automation and a CancellationToken Source // so we can cancel it later. CancellationTokenSource cts = new CancellationTokenSource(); Func <Task> handleTask = async() => { var startedTime = DateTime.Now; Console.WriteLine($"{DateTime.Now} {automation} event: {evt.DescriptionText}"); using (var operation = _telemetryClient.StartOperation <RequestTelemetry>(automation.ToString())) { _telemetryClient.TrackEvent("Automation Started", evt.GetDictionary()); try { // This runs the Handle method on the automation class await automation.Handle(cts.Token); } catch (TaskCanceledException) { TimeSpan executionTime = DateTime.Now - startedTime; _telemetryClient.TrackEvent($"Automation Cancelled", new Dictionary <string, string>() { { "WaitTime", executionTime.TotalSeconds.ToString() }, }); Console.WriteLine($"{DateTime.Now} {automation} event from {startedTime} cancelled."); } catch (Exception ex) { operation.Telemetry.Success = false; _telemetryClient.TrackException(ex); Console.WriteLine($"{DateTime.Now} {automation} {ex} {ex.Message}"); } } }; // Ready... go handle it! Task work = Task.Run(handleTask, cts.Token); // Hold on to the task and its cancellation token source for later. _taskManager.Track(work, cts, automation.GetType(), evt.DeviceId); } // Let's take this opportunity to get rid of any completed tasks. _taskManager.RemoveCompletedTasks(); }
async Task HubitatEventWatcherThread() { int wseRetryCount = 0; while (true) { try { Console.WriteLine($"{DateTime.Now} Connecting to Hubitat..."); using (var client = new ClientWebSocket()) { client.Options.RemoteCertificateValidationCallback += (a, b, c, d) => { return(true); }; await client.ConnectAsync(new Uri(_websocketUrl), CancellationToken.None); Console.WriteLine($"{DateTime.Now} Websocket success! Watching for events."); wseRetryCount = 0; ArraySegment <byte> buffer; while (client.State == WebSocketState.Open) { buffer = new ArraySegment <byte>(new byte[1024 * 4]); WebSocketReceiveResult reply = await client.ReceiveAsync(buffer, CancellationToken.None); string json = System.Text.Encoding.Default.GetString(buffer.ToArray()).TrimEnd('\0'); HubEvent evt = JsonConvert.DeserializeObject <HubEvent>(json); OnAutomationEvent(new AutomationEventEventArgs() { HubEvent = evt }); } } } catch (WebSocketException wse) { wseRetryCount++; int waitTimeInSecs = (wseRetryCount > 5) ? 150 : 5; Console.WriteLine($"{DateTime.Now} Hubitat websocket error! {wse.Message} -- Retrying in {waitTimeInSecs} seconds..."); await Task.Delay(TimeSpan.FromSeconds(waitTimeInSecs)); } catch (UriFormatException ufe) { Console.WriteLine($"{DateTime.Now} URI Format Exception! Fix your config! {ufe.Message}"); await Task.Delay(Timeout.InfiniteTimeSpan); } catch (Exception ex) { // Something unknown went wrong. I don't care what // because this method should run forever. Just mention it. Console.WriteLine($"{DateTime.Now} {ex} {ex.Message}"); } } }
public NotifyOnExteriorDoorOpen(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { NotificationDevices = new List <Speaker>() { _hub.GetDeviceByMappedName <Speaker>("Speaker.WebhookNotifier") as Speaker, _hub.GetDeviceByMappedName <Speaker>("Speaker.KitchenSpeaker") as Speaker }; HowLong = TimeSpan.FromMinutes(2); }
public CredentialContractWSService(RestClient <TUser, TToken> rest, HubClient <TUser, TToken> hub) : base(rest, hub) { _onUpdate = new HubEvent <TUser, TToken>(hub, Name, "onUpdate"); _onUpdateData = new HubEventData <TUser, TToken, AnyData>(hub, Name, "onUpdateData"); _onUpdateSelection = new HubEvent <TUser, TToken>(hub, Name, "onUpdateSelection"); _onUpdateSelectionData = new HubEventData <TUser, TToken, AnyData>(hub, Name, "onUpdateSelectionData"); _onUpdateValidation = new HubEventValidation <TUser, TToken, double>(hub, Name, "onUpdateValidation"); _onUpdateValidationData = new HubEventValidationData <TUser, TToken, double, AnyData>(hub, Name, "onUpdateValidationData"); _onUpdateValidationSelection = new HubEventValidation <TUser, TToken, double>(hub, Name, "onUpdateValidationSelection"); _onUpdateValidationSelectionData = new HubEventValidationData <TUser, TToken, double, AnyData>(hub, Name, "onUpdateValidationSelectionData"); }
public NotifyOnGatesOpen(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { HowLong = TimeSpan.Zero; NotifyOnClose = true; NotificationDevices = new List <Speaker>() { _hub.GetDeviceByMappedName <Speaker>("Speaker.WebhookNotifier") as Speaker, _hub.GetDeviceByMappedName <Speaker>("Speaker.KitchenSpeaker") as Speaker }; NotificationFormat = @"{0} is open."; }
/// <summary> /// Figures out the appropriate implementation of IAutomation based on the data in the event and returns it. /// </summary> /// <param name="evt"></param> /// <param name="hub"></param> /// <returns>An IEnumerable<IAutomation> containing the automations to be run for this event.</returns> public static IEnumerable <IAutomation> GetAutomations(HubEvent evt, HomeAutomationPlatform hub) { /* * Get the types from the assembly * where the type implements IAutomation and * the type has trigger attributes * where the trigger attribute names a mapped device that matches the device that caused the event * and the attribute also names a Capability that matches the device that caused the event * and the count of the matching trigger attributes is greater than 0 */ Dictionary <string, List <Type> > assemblies = MemoryCache.GetOrCreate("Assemblies", entry => { Dictionary <string, List <Type> > automationDictionary = new Dictionary <string, List <Type> >(); var temp = Assembly.LoadFrom(_automationAssembly).GetTypes() .Where(t => typeof(IAutomation).IsAssignableFrom(t)); foreach (var type in temp) { var keys = type.GetCustomAttributes <TriggerDeviceAttribute>().Select(t => $"{hub.LookupDeviceId(t.DeviceMappedName)}|{t.Capability.ToString().ToLower()}"); foreach (var key in keys) { if (automationDictionary.ContainsKey(key)) { automationDictionary[key].Add(type); } else { automationDictionary.Add(key, new List <Type> { type }); } } } return(automationDictionary); }); foreach (Type automation in assemblies[$"{evt.DeviceId}|{evt.Name}"]) { var thing = Activator.CreateInstance(automation, new Object[] { hub, evt }); if (thing is IAutomation automationSource) { yield return(automationSource); } } }
private static void StartRelevantAutomationHandlers(HubEvent evt) { // Get a reference to the automation var automations = AutomationFactory.GetAutomations(evt, _hub); foreach (IAutomation automation in automations) { // If this automation is already running, cancel all running instances _taskManager.CancelRunningInstances(automation.GetType(), evt.DeviceId); // Start a task to handle the automation and a CancellationToken Source // so we can cancel it later. CancellationTokenSource cts = new CancellationTokenSource(); Func <Task> handleTask = async() => { var startedTime = DateTime.Now; Console.WriteLine($"{DateTime.Now} {automation} event: {evt.DescriptionText}"); try { // This runs the Handle method on the automation class await automation.Handle(cts.Token); } catch (TaskCanceledException) { Console.WriteLine($"{DateTime.Now} {automation} event from {startedTime} cancelled."); } catch (Exception ex) { Console.WriteLine($"{DateTime.Now} {automation} {ex} {ex.Message}"); } }; // Ready... go handle it! Task work = Task.Run(handleTask, cts.Token); // Hold on to the task and its cancellation token source for later. _taskManager.Track(work, cts, automation.GetType(), evt.DeviceId); } // Let's take this opportunity to get rid of any completed tasks. _taskManager.RemoveCompletedTasks(); }
public LockFrontDoor(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { _service = new SmartThingsLockService(_hub.Configuration); }
public GarageEntryPowerAllowance(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { HowLong = TimeSpan.FromMinutes(30); }
public AuthContractWSService(RestClient <TUser, TToken> rest, HubClient <TUser, TToken> hub) : base(rest, hub) { _onUpdate = new HubEvent <TUser, TToken>(hub, Name, "onUpdate"); _onDataUpdate = new HubEventData <TUser, TToken, AnyData>(hub, Name, "onDataUpdate"); }
public DoorWatcherBase(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
public BarLights(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
private static void SendEventToMqtt(HubEvent evt) { _mqtt?.SendEventToMqttAsync(evt); }
public LivingRoomHolidayAutomation(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
public NotifyOnGatesOpen(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { HowLong = TimeSpan.Zero; NotifyOnClose = true; NotificationFormat = @"{0} is open."; }
public AutomationBase(HomeAutomationPlatform hub, HubEvent evt) { _hub = hub; _evt = evt; }
public NotifyOnExteriorDoorOpen(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { HowLong = TimeSpan.FromMinutes(2); }
public LivingRoomRemoteControl(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
public SampleAutomation(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
public NotifyOnDoorUnlock(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
public NotifyOnMailArrival(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
public PowerAllowanceBase(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
public BasementStairLighting(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
public NotifyOnFridgeDoorOpen(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { HowLong = TimeSpan.FromMinutes(1); NumberOfNotifications = 2; }
public PatioAndFloodlightAutomation(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
public NotifyOnSlidingDoorAndGatesOpen(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { }
public BasementStairwayPowerAllowance(HomeAutomationPlatform hub, HubEvent evt) : base(hub, evt) { HowLong = TimeSpan.FromMinutes(5); }