/// <summary>
        /// Initializes a new instance of the <see cref="NotifyChangeMonitor{T}"/> class.
        /// </summary>
        /// <param name="obj">Object to monitor.</param>
        public NotifyChangeMonitor(T obj)
        {
            this.obj = obj;

            this.obj.PropertyChanged += (sender, args) => PropertiesChanged.Add(args.PropertyName);
            this.obj.OnChanged       += (sender, wasChanged) => StateChanges.Add(wasChanged);
        }
        public virtual void FindDifferences(object oldState, object newState, StateChanges stateChanges, int maxDepth)
        {
            values = new Dictionary <string, StateChange>();

            if (oldState != null)
            {
                beingTraversed = BeingTraversed.Old;
                traverser.TraverseInstance(oldState, maxDepth, this);
            }

            if (newState != null)
            {
                beingTraversed = BeingTraversed.New;
                traverser.TraverseInstance(newState, maxDepth, this);
            }

            beingTraversed = BeingTraversed.Nothing;

            foreach (var kvp in values)
            {
                var change = kvp.Value;

                if (change.OldValue == null && change.NewValue != null)
                {
                    stateChanges.Changes.Add(change);
                }

                else if (change.OldValue != null && !change.OldValue.Equals(change.NewValue))
                {
                    stateChanges.Changes.Add(change);
                }
            }
        }
Exemple #3
0
        private void ManageNightLights()
        {
            Entity(HallPir !)
            .StateChanges
            .Where(e =>
                   e.New?.State == "on" &&
                   e.Old?.State == "off" &&
                   (IsNight || IsMorning || IsEvening))
            .Subscribe(
                s =>
            {
                Light.HallTak1.TurnOn(new { transition = 0 });
                Light.HallTak2.TurnOn(new { transition = 0 });
            }
                );

            Entity(HallPir !)
            .StateChanges
            .Where(e =>
                   e.New?.State == "off" &&
                   e.Old?.State == "on" &&
                   (IsNight || IsMorning || IsEvening) &&
                   !IsTimeNowBetween(TimeSpan.FromHours(5), TimeSpan.FromHours(10)))
            .NDSameStateFor(TimeSpan.FromMinutes(1))
            .Subscribe(
                s =>
            {
                Light.HallTak1.TurnOff(new { transition = 0 });
                Light.HallTak2.TurnOff(new { transition = 0 });
            }
                );
        }
Exemple #4
0
 public UptimeReport CalculateDurations()
 {
     StateChanges = StateChanges.OrderByDescending(r => r.NobreakState.Timestamp).ToList();
     for (int i = 0; i < StateChanges.Count; i++)
     {
         StateChanges[i].Duration = (i > 0 ? StateChanges[i - 1].NobreakState.Timestamp : CalculatedOn) - StateChanges[i].NobreakState.Timestamp;
     }
     return(this);
 }
Exemple #5
0
        private void AddStateChange(SaleStateChange stateChange, bool isInitialStateChange)
        {
            if (stateChange is null)
            {
                throw new BaristaException("invalid_sale_state_change", "The state change is empty.");
            }

            ValidateStateChange(stateChange.State, isInitialStateChange);
            StateChanges.Add(stateChange);
            SetUpdatedNow();
        }
        public virtual void FindDifferences
        (
            object oldState,
            object newState,
            StateChanges stateChanges,
            int maxDepth,
            Func <FieldInfo, IReadOnlyInstanceTraversalContext, bool> fieldIgnoreFunc       = null,
            Func <PropertyInfo, IReadOnlyInstanceTraversalContext, bool> propertyIgnoreFunc = null
        )
        {
            if (fieldIgnoreFunc == null)
            {
                fieldIgnoreFunc = (field, context) => false;
            }

            if (propertyIgnoreFunc == null)
            {
                propertyIgnoreFunc = (prop, context) => false;
            }

            fieldIgnoreFn    = fieldIgnoreFunc;
            propertyIgnoreFn = propertyIgnoreFunc;

            values = new Dictionary <string, StateChange>();

            if (oldState != null)
            {
                beingTraversed = BeingTraversed.Old;
                traverser.TraverseInstance(oldState, maxDepth, this);
            }

            if (newState != null)
            {
                beingTraversed = BeingTraversed.New;
                traverser.TraverseInstance(newState, maxDepth, this);
            }

            beingTraversed = BeingTraversed.Nothing;

            foreach (var kvp in values)
            {
                var change = kvp.Value;

                if (change.OldValue == null && change.NewValue != null)
                {
                    stateChanges.Changes.Add(change);
                }

                else if (change.OldValue != null && !change.OldValue.Equals(change.NewValue))
                {
                    stateChanges.Changes.Add(change);
                }
            }
        }
Exemple #7
0
 public override void Initialize()
 {
     Entity(AlarmSensor !)
     .StateChanges.Where(e =>
                         e.New.Attribute?.next_alarm_status == "ringing" &&
                         e.Old.Attribute?.next_alarm_status != "ringing")
     .Subscribe(s =>
     {
         // make a short delay
         RunIn(TimeSpan.FromSeconds(30), () => Speak("media_player.sovrum", "du har satt larm!"));
     });
 }
Exemple #8
0
    public void TrackStateChange(State <T> oldState, State <T> newState)
    {
        if (TrackChanges)
        {
            if (oldState != null)
            {
                StateChangeRecord <T> record = new StateChangeRecord <T>(oldState.Name, newState.Name, TimingFunction.Invoke());

                StateChanges.Add(record);
            }
        }
    }
Exemple #9
0
    public override Task InitializeAsync()
    {
        Entity(Calendar !)
        .StateChanges.Where(e => e.New.State == "on")
        .Subscribe(s =>
        {
            Speak("media_player.huset", "Viktigt meddelande");     // Important message
            Speak("media_player.huset", s.New?.Attribute?.message);
            Speak("media_player.huset", s.New?.Attribute?.description);
        });

        return(Task.CompletedTask);
    }
Exemple #10
0
    /// <summary>
    ///     Initialize, is automatically run by the daemon
    /// </summary>
    public override void Initialize()
    {
        // Set up the state management

        // When chromecast is going off
        // Entities("media_player.tv_nere")
        //     .StateChanges
        //     .Where(e => e.New?.State == "off" && e.Old?.State is object )
        //     .Subscribe(s =>
        //    {
        //        if (TvIsOn)
        //        {
        //            Log('TV is off, turnin off shield and tv')
        //            RunScript("tv_off_scene");
        //        }
        //    });
        // When state change on my media players, call OnMediaStateChanged
        Entities(TvMediaPlayers !)
        .StateChanges
        .Subscribe(s =>
        {
            OnMediaStateChanged(s.New, s.Old);
        });

        // When TV on (remote on), call OnTvTurnedOn
        Entity(RemoteTVRummet !)
        .StateChanges
        .Where(e =>
               e.Old?.State == "off" &&
               e.New?.State == "on")
        .Subscribe(s =>
        {
            LogDebug("TV remote status change from {from} to {to}", s.Old?.State, s.New?.State);
            OnTVTurnedOn();
        });


        // When ever TV remote activity changes, ie TV, Film, Poweroff call OnTvActivityChange
        Entity(RemoteTVRummet !)
        .StateAllChanges
        .Where(e => e.New?.Attribute?.current_activity != e.Old?.Attribute?.current_activity)
        .Subscribe(s =>
        {
            LogDebug("TV remote activity change from {from} to {to}", s.Old?.Attribute?.current_activity, s.New?.Attribute?.current_activity);
            OnTvActivityChange(s.New);
        });
    }
Exemple #11
0
        /// <summary>
        /// Generate a diff of the given objects, suitable
        /// for logging.
        ///
        /// You can control which members are included and how
        /// by marking your state objects with <see cref="AuditAttribute"/>.
        /// </summary>
        /// <param name="oldState">The old state - null is allowed</param>
        /// <param name="newState">The new state - null is allowed</param>
        /// <returns>A set of changes</returns>
        /// <exception cref="ArgumentException">Thrown if a value masker has been supplied, that does not implement the right interface</exception>
        public virtual StateChanges GetAuditReadyDiff(object oldState, object newState)
        {
            var auditChanges = new StateChanges();

            var changes = stateChangeFinder.GetChanges(oldState, newState);

            foreach (var change in changes.Changes)
            {
                if (change.MemberInfo is FieldInfo fieldInfo && !fieldInfo.IsPublic)
                {
                    // we do not want private/protected fields
                    continue;
                }

                if (change.MemberInfo is PropertyInfo propInfo && propInfo.GetMethod != null && !propInfo.GetMethod.IsPublic)
                {
                    // we do not want private/protected properties
                    continue;
                }

                if (change.MemberInfo.HasAttribute(typeof(AuditAttribute)))
                {
                    var attr = change.MemberInfo.GetCustomAttribute <AuditAttribute>();

                    if (!attr.Include)
                    {
                        continue;
                    }

                    if (attr.DoMaskValue)
                    {
                        if (!attr.ValueMasker.ImplementsInterface(typeof(IAuditValueMasker)))
                        {
                            throw new ArgumentException($"A {nameof(AuditAttribute.ValueMasker)} must implement {typeof(IAuditValueMasker).Name}, which {attr.ValueMasker.Name} does not.");
                        }

                        var masker = (IAuditValueMasker)container.Resolve(attr.ValueMasker);
                        change.OldValue = masker.MaskValue(change.OldValue);
                        change.NewValue = masker.MaskValue(change.NewValue);
                    }
                }

                auditChanges.Changes.Add(change);
            }

            return(auditChanges);
        }
Exemple #12
0
    public override Task InitializeAsync()
    {
        if (!CheckConfig())
        {
            return(Task.CompletedTask);
        }

        Entity(DoorSensor !)
        .StateChanges
        .Where(e => e.New?.State == "on")
        .Subscribe(s => GreetIfJustArrived(s.New.EntityId));

        StateChanges
        .Where(
            e => e.New.EntityId.EndsWith(PresenceCriteria !) &&
            e.New?.State == "Nyss anlänt")
        .Subscribe(s => GreetIfJustArrived(s.New.EntityId));

        return(Task.CompletedTask);
    }
Exemple #13
0
    /// <summary>
    ///     Initialize, is automatically run by the daemon
    /// </summary>
    public override void Initialize()
    {
        // Set up the state management

        // When chromecast is going off
        // Entities("media_player.tv_nere")
        //     .StateChanges
        //     .Where(e => e.New?.State == "off" && e.Old?.State is object )
        //     .Subscribe(s =>
        //    {
        //        if (TvIsOn)
        //        {
        //            Log('TV is off, turnin off shield and tv')
        //            RunScript("tv_off_scene");
        //        }
        //    });
        // When state change on my media players, call OnMediaStateChanged
        Entities(TvMediaPlayers !)
        .StateChanges
        .Subscribe(s => OnMediaStateChanged(s.New, s.Old));

        // When TV on (remote on), call OnTvTurnedOn
        Entity(RemoteTVRummet !)
        .StateChanges
        .Where(e =>
               e.Old?.State == "off" &&
               e.New?.State == "on")
        .Subscribe(s => OnTVTurnedOn());


        // When ever TV remote activity changes, ie TV, Film, Poweroff call OnTvActivityChange
        Entity(RemoteTVRummet !)
        .StateAllChanges
        .Where(e => e.New?.Attribute?.current_activity != e.Old?.Attribute?.current_activity)
        .Subscribe(s => OnTvActivityChange(s.New));

        // This function does not contain any async calls so just return completed task
        // return Task.CompletedTask;
    }
Exemple #14
0
    /// <summary>
    ///     Initialize the automations
    /// </summary>
    /// <remarks>
    ///     - Schedules check every minute if heater should be on or off depending on temperature
    ///     - Set the manually started flag if heater is turn on and not turned on by this script
    /// </remarks>
    public override void Initialize()
    {
        // Get the state if manually started from statestorage
        RunEveryMinute(0, () => HandleCarHeater());

        Entity(HeaterSwitch !)
        .StateChanges
        .Where(e => e.New.State == "on")
        .Subscribe(s =>
        {
            if (_appChangedState == false)
            {
                // It is manually turned on
                Storage.IsManualState = true;
            }
            else
            {
                Storage.IsManualState = false;
            }
            _appChangedState = false;
        });
    }
Exemple #15
0
        public UptimeReport CalculateUptimePerIntervals()
        {
            UptimePerIntervals = RelevantTimespans.Select(relevantTimespan =>
            {
                var since       = CalculatedOn - relevantTimespan;
                var events      = StateChanges.Where(s => s.NobreakState.Timestamp >= since).ToList();
                var rightBefore = StateChanges.SkipWhile(s => s.NobreakState.Timestamp >= (events.LastOrDefault()?.NobreakState.Timestamp ?? DateTime.Now)).FirstOrDefault();
                if (rightBefore != null)
                {
                    events.Add(rightBefore);
                }
                var sumPerState = PossibleStates.Select(s => new KeyValuePair <PowerStates, TimeSpan>(s, TimeSpan.Zero)).ToDictionary();
                for (int i = 0; i < events.Count; i++)
                {
                    sumPerState[events[i].PowerState] += events[i].NobreakState.Timestamp < since
                        ? events[i].Duration - (CalculatedOn - relevantTimespan - events[i].NobreakState.Timestamp)
                        : events[i].Duration;
                }
                var sum = TimeSpan.Zero;
                foreach (var state in sumPerState)
                {
                    sum += state.Value;
                }

                return(new UptimeInInterval
                {
                    UptimeStates = sumPerState.Select(stateSum => new UptimeState
                    {
                        ShareTimespan = stateSum.Value,
                        SharePercentage = stateSum.Value / sum * 100,
                        PowerState = stateSum.Key
                    }).ToList(),
                    Since = since,
                    TimeSpan = relevantTimespan
                });
            }).ToList();
            return(this);
        }
Exemple #16
0
        /// <summary>
        /// Generate a diff of the given objects, suitable
        /// for logging.
        ///
        /// You can control which members are included and how
        /// by marking your state objects with <see cref="AuditAttribute"/>.
        /// </summary>
        /// <param name="oldState">The old state - null is allowed</param>
        /// <param name="newState">The new state - null is allowed</param>
        /// <returns>A set of changes</returns>
        /// <exception cref="ArgumentException">Thrown if a value masker has been supplied, that does not implement the right interface</exception>
        public virtual StateChanges GetAuditReadyDiff(object oldState, object newState)
        {
            var auditChanges = new StateChanges();

            var changes = stateChangeFinder.GetChanges(oldState, newState, ShouldIgnoreMember, ShouldIgnoreMember);

            foreach (var change in changes.Changes)
            {
                if (change.MemberInfo is FieldInfo fieldInfo && !fieldInfo.IsPublic)
                {
                    // we do not want private/protected fields
                    continue;
                }

                if (change.MemberInfo is PropertyInfo propInfo && propInfo.GetMethod != null && !propInfo.GetMethod.IsPublic)
                {
                    // we do not want private/protected properties
                    continue;
                }

                if (change.MemberInfo.HasAttribute(typeof(AuditAttribute)))
                {
                    var attr = change.MemberInfo.GetCustomAttribute <AuditAttribute>();

                    if (attr.DoMaskValue)
                    {
                        var masker = GetValidValueMaskerOrThrow(attr);

                        change.OldValue = masker.MaskValue(change.OldValue);
                        change.NewValue = masker.MaskValue(change.NewValue);
                    }
                }

                auditChanges.Changes.Add(change);
            }

            return(auditChanges);
        }
Exemple #17
0
    /// <summary>
    ///     Initialize, is automatically run by the daemon
    /// </summary>
    public override void Initialize()
    {
        // Set up the state management

        // When state change on my media players, call OnMediaStateChanged
        Entities(TvMediaPlayers !)
        .StateChanges
        .Subscribe(s => OnMediaStateChanged(s.New, s.Old));

        // When TV on (remote on), call OnTvTurnedOn
        Entity(RemoteTVRummet !)
        .StateChanges
        .Where(e => e.New?.State == "on")
        .Subscribe(s => OnTVTurnedOn());

        // When ever TV remote activity changes, ie TV, Film, Poweroff call OnTvActivityChange
        Entity(RemoteTVRummet !)
        .StateAllChanges
        .Where(e => e.New?.Attribute?.current_activity != e.Old?.Attribute?.current_activity)
        .Subscribe(s => OnTvActivityChange(s.New));

        // This function does not contain any async calls so just return completed task
        // return Task.CompletedTask;
    }
Exemple #18
0
    public override void Initialize()
    {
        _Emoji = Type ! == "Washer" ? "🧼" : "🧺";

        Entity(PowerSensor !)
        .StateChanges
        .Where(
            e => e.New?.ToStateBool() == true)
        .NDSameStateFor(TimeSpan.FromSeconds(90))
        .Subscribe(s => Running());

        Entity(PowerSensor !)
        .StateChanges
        .Where(
            e => e.New?.ToStateBool() == false)
        .NDSameStateFor(TimeSpan.FromSeconds(270))
        .Subscribe(s => Clean());

        Entity(HatchSensor !)
        .StateChanges
        .Where(
            e => e.New?.State == "on")
        .Subscribe(s => Emptied());
    }
Exemple #19
0
 /// <summary>
 /// Creates a new RichTextModel with the formatting from this RichText.
 /// </summary>
 public RichTextModel ToRichTextModel()
 {
     return(new RichTextModel(StateChangeOffsets, StateChanges.Select(ch => ch.Clone()).ToArray()));
 }
        public StateChangeFinderWorker_ArrayTests()
        {
            stateChanges = new StateChanges();

            worker = new StateChangeFinderWorker(new InstanceTraverser());
        }
Exemple #21
0
        /// <summary>
        ///     Initialize the app
        /// </summary>
        public void Initialize()
        {
            _app.Entity("binary_sensor.kitchen")
            .StateChanges
            .Where(e => e.New?.State == "on" && e.Old?.State == "off")
            .Subscribe(_ =>
            {
                // Just for the testing of all these
                _app.Entity("light.kitchen").TurnOn(new { brightness = 100 });
                _app.Entity("light.kitchen").TurnOff(new { brightness = 100 });
                _app.Entity("light.kitchen").Toggle(new { brightness = 100 });
            }
                       );

            _app.Entity("binary_sensor.livingroom")
            .StateChanges
            .Where(e => e.New?.State == "on" && e.Old?.State == "off")
            .Subscribe(_ => _app.Entity("sensor.mysensor").SetState(20, new { battery_level = 90 }));

            _app.Entities(n => n.EntityId !.EndsWith("entities", StringComparison.InvariantCultureIgnoreCase)).StateChanges.Where(s => s.New.State == "on").Subscribe(_ => _app.Entity("light.kitchen").TurnOn());
            _app.Entities(n => n.EntityId !.EndsWith("entities", StringComparison.InvariantCultureIgnoreCase)).StateChanges.Where(s => s.New.State == "off").Subscribe(_ => _app.Entity("light.kitchen").TurnOff());

            _app.Entity("sensor.temperature")
            .StateAllChanges
            .Where(e => e.New?.Attribute?.battery_level < 15)
            .Subscribe(_ => _app.CallService("notify", "notify", new { title = "Hello from Home Assistant" }));

            _app.EventChanges
            .Where(e => e.Event == "hello_event")
            .Subscribe(_ => _app.Entity("light.livingroom").TurnOn());

            _app.EventChanges
            .Where(e => e.Event == "bye_event")
            .Subscribe(_ => _app.Entity("light.livingroom").TurnOff());

            _app.SetState("sensor.any_sensor", 20, new { battery_level = 70 });
            _app.SetState("sensor.any_sensor2", 20, new { battery_level = 70 });

            _app.Entity("binary_sensor.test_state_entity")
            .StateChanges
            .Subscribe(_ =>
            {
                if (_app.State("sensor.some_other_entity")?.State == "on")
                {
                    _app.Entity("light.state_light").TurnOn();
                }
            });

            _app.RunIn(TimeSpan.FromMilliseconds(100), () => _app.Entity("binary_sensor.fake_run_in_happened").TurnOn());
            _app.RunEveryMinute(0, () => _app.Entity("binary_sensor.fake_run_every_minute_happened").TurnOn());
            _app.RunEveryHour("15:00", () => _app.Entity("binary_sensor.fake_run_every_hour_happened").TurnOn());
            _app.RunDaily("23:00:00", () => _app.Entity("binary_sensor.fake_run_daily_happened").TurnOn());
            _timer = _app.RunEveryMinute(0, TestTimerDisposal);
        }
Exemple #22
0
        private void mstp_thread()
        {
            try
            {
                StateChanges state_change = StateChanges.Reset;

                while (m_port != null)
                {
                    if (StateLogging)
                    {
                        Trace.WriteLine(state_change.ToString(), null);
                    }
                    switch (state_change)
                    {
                    case StateChanges.Reset:
                        state_change = Initialize();
                        break;

                    case StateChanges.DoneInitializing:
                    case StateChanges.ReceivedUnexpectedFrame:
                    case StateChanges.Reply:
                    case StateChanges.DeferredReply:
                    case StateChanges.SawTokenUser:
                        state_change = Idle();
                        break;

                    case StateChanges.GenerateToken:
                    case StateChanges.FindNewSuccessor:
                    case StateChanges.SendMaintenancePFM:
                    case StateChanges.SoleMasterRestartMaintenancePFM:
                    case StateChanges.NextStationUnknown:
                        state_change = PollForMaster();
                        break;

                    case StateChanges.DoneWithPFM:
                    case StateChanges.ResetMaintenancePFM:
                    case StateChanges.ReceivedReplyToPFM:
                    case StateChanges.SendToken:
                        state_change = PassToken();
                        break;

                    case StateChanges.ReceivedDataNeedingReply:
                        state_change = AnswerDataRequest();
                        break;

                    case StateChanges.ReceivedToken:
                    case StateChanges.SoleMaster:
                    case StateChanges.DeclareSoleMaster:
                    case StateChanges.SendAnotherFrame:
                        state_change = UseToken();
                        break;

                    case StateChanges.NothingToSend:
                    case StateChanges.SendNoWait:
                    case StateChanges.ReplyTimeOut:
                    case StateChanges.InvalidFrame:
                    case StateChanges.ReceivedReply:
                    case StateChanges.ReceivedPostpone:
                        state_change = DoneWithToken();
                        break;

                    case StateChanges.SendAndWait:
                        state_change = WaitForReply();
                        break;
                    }
                }
                Trace.WriteLine("MSTP thread is closing down", null);
            }
            catch (Exception ex)
            {
                Trace.TraceError("Exception in MSTP thread: " + ex.Message);
            }

            m_is_running = false;
        }
        private void SetupSubscriptions()
        {
            LogTrace("SetupSubscriptions()");
            foreach (var entityId in _presenceEntityIds)
            {
                _app.Entity(entityId)
                .StateAllChanges
                .Where(e => e.Old?.State == "off" && e.New?.State == "on" || e.Old?.State == "on" && e.New?.State == "on")
                .Subscribe(s =>
                {
                    LogDebug("Presence event: {entityId}", s.New.EntityId);
                    HandleEvent();
                });
            }

            foreach (var entityId in _keepAliveEntityIds)
            {
                _app.Entity(entityId)
                .StateChanges
                .Where(e => e.Old?.State == "off" && e.New?.State == "on" || e.Old?.State == "on" && e.New?.State == "on")
                .Subscribe(s =>
                {
                    LogDebug("Keep Alive event: {entityId}", s.New.EntityId);
                    HandleEvent();
                });
            }

            foreach (var entityId in _controlEntityIds.Union(_nightControlEntityIds))
            {
                _app.Entity(entityId)
                .StateChanges
                .Where(e => e.Old?.State == "on" && e.New?.State == "off")
                .Subscribe(s =>
                {
                    LogDebug("Entitiy Manually Turned Off: {entityId}", s.New.EntityId);
                    SetRoomState(RoomState.Idle);
                });
            }

            foreach (var entityId in _controlEntityIds.Union(_nightControlEntityIds))
            {
                _app.Entity(entityId)
                .StateAllChanges
                .Where(e => e.Old?.State == "on" && e.New?.State == "on" &&
                       e.New?.Context?.UserId != null &&
                       (e.Old?.Attribute?.brightness != e.New?.Attribute?.brightness || e.Old?.Attribute?.color_temp != e.New?.Attribute?.color_temp))

                .Subscribe(s =>
                {
                    LogDebug("Brightness/Colour Manually Changed: {entityId}", s.New.EntityId);
                    DisableCircadian();
                });
            }

            foreach (var entityId in _controlEntityIds.Union(_nightControlEntityIds))
            {
                _app.Entity(entityId)
                .StateChanges
                .Where(e => e.Old?.State == "off" && e.New?.State == "on")
                .Subscribe(s =>
                {
                    LogDebug("Entitiy Manually Turned On: {entityId}", s.New.EntityId);
                    SetRoomState(RoomState.Override);
                });
            }

            _app.Entity(_roomConfig.EnabledSwitchEntityId)
            .StateChanges
            .Subscribe(s =>
            {
                LogDebug("Enabled Switch event changed to: {state}", s.New.State);
                if (s.New.State == "on")
                {
                    SetRoomState(RoomState.Idle);
                }
                if (s.New.State == "off")
                {
                    SetRoomState(RoomState.Disabled);
                }
            });

            if (_app.States.Any(s => s.EntityId == _roomConfig.NightTimeEntityId))
            {
                _app.Entity(_roomConfig.NightTimeEntityId !)
                .StateChanges
                .Subscribe(s =>
                {
                    LogDebug("Night Mode Switched: {state}", s.New.State);
                    NightModeChanged(s.New.State);
                });
            }
        }