That’s workable with multiple methods. But as seen in the attributes, my schedule differs for the weekend. A non-workday should also have the same schedule as the weekend. Thus the dilemma. The executed code is the same, so I’d prefer to keep it DRY, execution time differs only. That’s what I’m trying to do anyway. BTW a weekend is considered not a workday as well as holidays.
Ok i see. The only problem I have with using the Workday sensor is that I would have to implement logic that only applies if you are using that sensor.
How about a Schedule attribute you could inherit from and implement your own schedule logic.
Basically the scheduler would call a GetNextOccurence function and you could implement that the way you want to.
Sounds fine!
Man I know I’m throwing requests like crazy, but it’s only because I’m so stoked about this project.
It would be good to get some helper classes to handle timers. Right now I don’t see any way other than swallowing events (which is messy) to get a callback from a HASS Helper Timer.
Like timers in c#? Can you show me code?
I’ve worked the schedule and the timer thing (I’m a bit rusty in .NET) so nevermind, sorry.
Strange behavior I’m witnessing.
Within the the class in which the automation endpoints exist, I’m instantiating objects in the constructor and attempting to persist them across calls. But it appears that they’re being re-instantiated with each automation endpoint call, I can see the constructor being called each time. Can you explain? They must be dynamically created at runtime.
Because of this various variables will not persist unless they are abstracted to a static class.
Is there a way to determine which entity fired the automation if you use multiple ‘triggers’ in the same endpoint?
#1 There is now a way to create custom triggers and schedules: 4. Triggers · anhaehne/hhnl.HomeAssistantNet Wiki (github.com)
#2 Yes, the automation classes are transient, meaning they get newly created for each automation run. If you want to persist something between multiple runs you should create static variables or save them in Home Assistant.
#3 You can inject the current event. 7. Events · anhaehne/hhnl.HomeAssistantNet Wiki (github.com) Here you will get the source event as JsonElement.
PS: The newest version 0.8.0+ has a breaking change. RunOnStart is now an attribute and not part of the AutomationAttribute anymore. See: 4. Triggers · anhaehne/hhnl.HomeAssistantNet Wiki (github.com)
Also some namespaces have changed.
Since the latest, I’ve patched up all the breaking changes, I can build local but it will not start or build on HASS. Looks like the generator might be twisted at the axel.
Unhandled exception. System.ArgumentException: An item with the same key has already been added. Key: CS4HA.MasterBath.Occupancy
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) in System.Private.CoreLib.dll:token 0x60062ce+0x1a0
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value) in System.Private.CoreLib.dll:token 0x60062c1+0x0
at System.Linq.Enumerable.ToDictionary[TSource,TKey](IEnumerable`1 source, Func`2 keySelector, IEqualityComparer`1 comparer) in System.Linq.dll:token 0x600011d+0x75
at hhnl.HomeAssistantNet.Automations.Automation.AutomationRegistry..ctor(IGeneratedMetaData generatedMetaData, IAutomationInfoProvider automationInfoProvider, Assembly assembly) in hhnl.HomeAssistantNet.Automations.dll:token 0x60000a2+0x5b
at hhnl.HomeAssistantNet.Automations.Automation.AutomationStartup.<ConfigureServiceInternal>b__3_8(IServiceProvider s) in hhnl.HomeAssistantNet.Automations.dll:token 0x60000c3+0x0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context) in Microsoft.Extensions.DependencyInjection.dll:token 0x600007e+0x0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000091+0x33
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000079+0x59
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000077+0x0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000090+0x4e
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000076+0x39
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000091+0x4f
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000079+0x59
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000077+0x0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000090+0x4e
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000074+0x12
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope) in Microsoft.Extensions.DependencyInjection.dll:token 0x600016d+0x0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) in Microsoft.Extensions.DependencyInjection.dll:token 0x60000fd+0x3e
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000103+0xd
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) in Microsoft.Extensions.DependencyInjection.Abstractions.dll:token 0x600007b+0x34
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) in Microsoft.Extensions.DependencyInjection.Abstractions.dll:token 0x600007c+0xe
at hhnl.HomeAssistantNet.Automations.Automation.AutomationStartup.<>c.<ConfigureServiceInternal>b__3_1(IServiceProvider s) in hhnl.HomeAssistantNet.Automations.dll:token 0x60001b8+0x0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context) in Microsoft.Extensions.DependencyInjection.dll:token 0x600007e+0x0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000091+0x33
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000079+0x59
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000077+0x0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000090+0x4e
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context) in Microsoft.Extensions.DependencyInjection.dll:token 0x600007d+0x14
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000091+0x41
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000079+0x59
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000077+0x0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000090+0x4e
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000074+0x12
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope) in Microsoft.Extensions.DependencyInjection.dll:token 0x600016d+0x0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) in Microsoft.Extensions.DependencyInjection.dll:token 0x60000fd+0x3e
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000103+0xd
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) in Microsoft.Extensions.DependencyInjection.Abstractions.dll:token 0x600007a+0xe
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken) in Microsoft.Extensions.Hosting.dll:token 0x6000041+0xc4
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token) in Microsoft.Extensions.Hosting.Abstractions.dll:token 0x600001d+0x93
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token) in Microsoft.Extensions.Hosting.Abstractions.dll:token 0x600001d+0x1be
at CS4HA.Startup.<Main>(String[] args) in CS4HA.dll:token 0x600008f+0xc
I cleaned out the deploy folder and restarted, seems to be good.
As far as I can see, NoTrack is now missing.
This sounds amazing… like some I work in C# for a living and trying to understand template’ing an automation and along with YAMAL just is alien some how.
What been everyone’s experience been so far wit this add-on… I know its new///
-Aaron
I have been able to get everything working (Intellisense for entities, remote debugging, deployment) as expected and have converted all my existing automations. It is so nice being able to work in C# rather than the UI. Thanks Andre, I really hope this project stays afloat.
Hey guys,
I’m new to HA, but a C# dev, so discover this addon with a lot of interest.
I’m trying to convert a little YAML script for a start, which works with a Hue light.
I just don’t figure how to change color on the light ?
The hue light is HomeAssistant.Lights._0x0017880100f56187
but this object does not seems to have any brightness_pct nor color attribute, can’t figure out to make this work.
Could you share your C# automations ? i’m quite sure it would help beginers like to me understand how this works.
Thanks !
You can call all services available in HA like this: 3. Calling services · anhaehne/hhnl.HomeAssistantNet Wiki (github.com)
You can look at service data here: Light - Home Assistant (home-assistant.io)
In your example it would probably be something like this:
public class Test
{
private readonly IHomeAssistantClient _homeAssistantClient;
public Test(IHomeAssistantClient homeAssistantClient)
{
_homeAssistantClient = homeAssistantClient;
}
// We use the NoTack attribute to not run this automation when the light changes.
// Alternatively you can request the light entity in the constructor.
public async Task MyAutomation([NoTrack]HomeAssistant.Lights._0x0017880100f56187 myLight)
{
// TODO: Add your logic here
await _homeAssistantClient.CallServiceAsync(domain: "light",
service: "turn_on",
targetId: myLight.UniqueId,
serviceData: new
{
brightness = 130,
rgb_color = new[] { 255, 0, 0 }
});
}
}
Hey Limeray ! First of all many many thanks for the awesome works
Well my question is more “how should I know it’s a service I need to call ?”.
I now understand your exemple, but honestly I was not aware that to change the color (or brightness or whatever) I need to call the turn_on service.
I’m quite sure it’s related to the fact that I’m not familiar with HA !
Just looked at your second link, this IS the documentation I was missing. I’ll guess I have to search more in the HA docs to get my answer !
Regards,
Hello there !
It seems I’m having some issues with scripts that do not trigger by C# for HA. It’s based on HA automations that launch a script every morning :
- id: '1641585609160'
alias: Bouchon
description: ''
trigger:
- platform: time
at: 07:50
condition: []
action:
- service: script.waze
data: {}
mode: single
And then C# for HA has a dedicated classe :
public WazeAutomations(ILogger<WazeAutomations> logger,
IHomeAssistantClient homeAssistantClient,
HomeAssistant.Lights.PhilipsLct0018761f500LevelLightColorOnOff hue, HomeAssistant.Sensors.Taf trajet)
{
_logger = logger;
_homeAssistantClient = homeAssistantClient;
_hue = new EasyLight(hue.UniqueId, homeAssistantClient);
_trajet = trajet;
}
[Automation(reentryPolicy: ReentryPolicy.Discard)]
public async Task WazeBouchonAutomation(CancellationToken ct, [Snapshot]HomeAssistant.Scripts.Waze waze)
{
(...)
}
The morning the automatiion is triggered by HA, but nothing in C# for HA (no trace for execution looking at the automation.
Rebuilding and deploy solved the issu. But yesterday the automation had never stop (I had to manually stop it, and now it appears as Cancelled). And this morning it does not trigget at all again
I was having absolutly no issue since february, my Ha is always up to date. Do you have any clue ?
Regards,
Sometimes automation get stuck in the running state but that isn’t impacting the automation. So the state says running but the automation has completed successfully. Can you add logging to your automation to see if the automation really compeletes? There is a wiki entry on github on how to setup the logging.
I do have logging but I’m also sure it has not completed because when the automation start a light is on and then it’s off at the end
edit: or maybe the call for turning the light off did not work, and as the call was
await _hue.TurnOffAsync();
it has waited ?
But my main concern is about the automation that does not trigger this morning, it should have!
this morning still no automation on C# for HA, even if the HA automation had triggered ?
Ok so, as last time, I had to rebuild&deploy on C# for HA for the automation to trigger again. I don’t changer anything else. It’s weird and a little bit concerning ?