Skip to content

Event Timings

Leonard Sperry edited this page Feb 29, 2024 · 9 revisions

One of the advantages HaKafkaNet has over other integrations is that, because it uses Kafka, you can be assured that, at startup, your application can be aware of states for all Home Assistant entities. Additionally, for delayed or scheduled automations, it can even handle missed events and make sure states of entities are set appropriately. It does this by reading a compacted topic from the beginning. This also means that it can lead to some interesting interactions where your automations are concerned. This page will outline all the various edge cases you may encounter.

It is important to understand how the EventTiming enumeration is used to handle events in relation to your automations. Each state change will be associated with exactly one value from the enumeration. Your automations can listen for any combination of values.

By default, most automations only listen to events where the timing is set to EventTiming.PostStartup. So, for example, when you have an automation to turn on a light based on a motion/presence sensor, the light will only turn on at the moment motion is detected. Events in this scenario that happened before startup will not be handled.

You can however set the EventTimings property of your automations to any value. For example, the SunAutomation abstract class uses the EventTiming.Durable value, which is used with some other strategies to make all sun-based automations durable, meaning that they survive restarts of either Home Assistant or HaKafkaNet.

Here is the EventTiming enumeration as defined by the framework.

[Flags]
public enum EventTiming
{
    /// <summary>
    /// There is no corresponding cache entry for the state currently being handled
    /// </summary>
    PreStartupNotCached =           0b000001,
    /// <summary>
    /// State currently being handled happened before the most recent cach entry
    /// </summary>
    PreStartupPreLastCached =       0b000010,
    /// <summary>
    /// State currently being handled matches the most recent cache entry
    /// </summary>
    PreStartupSameAsLastCached =    0b000100,
    /// <summary>
    /// State currently being handled does not match the most recent cache entry, but occurred simultaneously with the cached entry
    /// (extreme edge case)
    /// </summary>
    PreStartupSameTimeLastCached =  0b001000,
    /// <summary>
    /// State currently being handled happened after the most recent cach entry
    /// </summary>
    PreStartupPostLastCached =      0b010000,
    /// <summary>
    /// Event happened after startup (may or may not be cached)
    /// </summary>
    PostStartup =                   0b100000,
    /// <summary>
    /// Used for making durable schedulable automations, but will not trigger event if item was not cached.
    /// For certain edge cases where the cache was wiped and compaction has not run, where old events may exist in topic
    /// </summary>
    DurableIfCached =               0b110100,
    /// <summary>
    /// Primarily used for schedulable events that need to survive restarts 
    /// </summary>
    Durable =                       0b110101,
    /// <summary>
    /// When IAutomation.EventTiming is set to this value, all events will be passed to the IAutomation
    /// </summary>
    All =                           0b111111
}

Druable

The Durable and DurableIfCached entries are intended for schedulable automations to be durable (survive restarts). The prebuilt, durable automations, including the sun-based automations use Durable by default. In most cases, this will suite your needs. However, if your cache is cleared before startup, and your system has been down for a while, and your automation is configured with ShouldExecutePastEvents as true, there could be cases where a durable automation could handle multiple outdated events at start up. If this is a case you are worried about, you should use the DurableIfCached option instead.

Clone this wiki locally