public void OnSunset()
        {
            _relayBoard.On(Enums.Relay.LightsGarden);

            var lightsOffEvent = _timerEvents.GetEvent(Enums.TimedEvent.OnLightsOff);

            lightsOffEvent.Enable();

            _timerEvents.UpdateEvent(Enums.TimedEvent.OnLightsOff, lightsOffEvent);
        }
Exemple #2
0
        private async Task GarageDoorStateChanged(object sender)
        {
            if (sender is Sensor sensor)
            {
                if (_alarmState.SensorArmed(sensor.Type) && GarageDoorOpen())
                {
                    await _alarmState.Tripped(sensor.Type);
                }
                else if (GarageDoorOpen())
                {
                    _timerEvents.UpdateEvent(TimedEvent.GarageDoorOperatedEnd, new Domain.TimedEvent(_clock.Now.AddTimeSpan(5.Minutes()), true));
                }

                await _mediator.Send(new UpdateReportedPropertyCommand(nameof(GarageDoorOpen), GarageDoorOpen()));
            }
        }
Exemple #3
0
        public async Task UpdateWeatherData(CancellationToken cancellationToken)
        {
            int LightsOffMinutesUnder30(TimeSpan timeSpan)
            {
                return(timeSpan.Minutes > 30 ? timeSpan.Minutes - 30 : timeSpan.Minutes);
            }

            bool LightsOffEnabled(TimeSpan sunset1, TimeSpan sunrise1)
            {
                return(_clock.Now.Within(sunset1, sunrise1));
            }

            bool ShouldLightsBeOn(TimeSpan sunset)
            {
                return(_clock.Now.TimeSpan() > sunset);
            }

            try
            {
                var response = await ResilientCall.ExecuteWithRetry(
                    async() => await _restClient.GetAsync(_openWeatherApiUrl, cancellationToken)
                    );

                if (response.Outcome != OutcomeType.Successful)
                {
                    Log.Error(response.FinalException, "Error getting weather data");
                    return;
                }

                var content = await response.Result.Content.ReadAsStringAsync();

                var result = JsonConvert.DeserializeObject <OpenWeatherResult>(content, Config.JsonSettings);

                var sunrise   = new TimedEvent(result.Sys.Sunrise.LocalTimeSpanFromUnixTime(), true);
                var sunset    = new TimedEvent(result.Sys.Sunset.LocalTimeSpanFromUnixTime(), true);
                var lightsOff = new TimedEvent(new TimeSpan(00, LightsOffMinutesUnder30(sunset.TriggerTime), 00), LightsOffEnabled(sunset.TriggerTime, sunrise.TriggerTime));

                if (ShouldLightsBeOn(sunset.TriggerTime))
                {
                    _lightsController.OnSunset();
                }

                var eventsToUpdate = new ConcurrentDictionary <Enums.TimedEvent, TimedEvent>();

                var onSunriseEvent   = eventsToUpdate.AddOrUpdate(Enums.TimedEvent.OnSunrise, sunrise, (key, oldValue) => sunrise);
                var onSunsetEvent    = eventsToUpdate.AddOrUpdate(Enums.TimedEvent.OnSunset, sunset, (key, oldValue) => sunset);
                var onLightsOffEvent = eventsToUpdate.AddOrUpdate(Enums.TimedEvent.OnLightsOff, lightsOff, (key, oldValue) => lightsOff);

                foreach (var evnt in eventsToUpdate)
                {
                    _timerEvents.UpdateEvent(evnt.Key, evnt.Value);
                }

                await _mediator.Send(new UpdateReportedPropertiesCommand(new TwinCollection
                {
                    [nameof(Enums.TimedEvent.OnSunrise)] = onSunriseEvent,
                    [nameof(Enums.TimedEvent.OnSunset)] = onSunsetEvent,
                    [nameof(Enums.TimedEvent.OnLightsOff)] = onLightsOffEvent
                }), cancellationToken);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error updating weather data");
            }
        }
Exemple #4
0
        public async Task Tripped(Sensor sensor)
        {
            var sensorDetails = SensorDetails(sensor);

            if (sensor.IsSensorTamper())
            {
                Log.Information($"[ALARMSTATE] TRIPPED Sensor: {sensor}");
                TrippedSensors.Add(sensor);

                _relayBoard
                .Relay(Enums.Relay.AlarmStrobe)
                .Relay(Enums.Relay.AlarmSiren)
                .On();

                TurnLightsOnAtNight();

                _timerEvents.UpdateEvent(Enums.TimedEvent.StrobeOff, new TimedEvent(_clock.Now.AddTimeSpan(Config.StrobeAlarm), true));
                _timerEvents.UpdateEvent(Enums.TimedEvent.SirenOff, new TimedEvent(_clock.Now.AddTimeSpan(Config.SirenAlarm), true));

                await _mediator.Publish(new SendRichPushNotificationCommand
                {
                    Title    = sensorDetails.Title,
                    Body     = "Sensor has been tampered with...",
                    CameraId = sensorDetails.CameraId
                });
            }

            if (sensor.IsSensorOutdoor())
            {
                Log.Information($"[ALARMSTATE] TRIPPED Sensor: {sensor}");
                TrippedSensors.Add(sensor);

                _relayBoard
                .Relay(Enums.Relay.AlarmStrobe)
                .Relay(Enums.Relay.AlarmSiren)
                .On();

                TurnLightsOnAtNight();

                _timerEvents.UpdateEvent(Enums.TimedEvent.StrobeOff, new TimedEvent(_clock.Now.AddTimeSpan(Config.StrobeAlarm), true));
                _timerEvents.UpdateEvent(Enums.TimedEvent.SirenOff, new TimedEvent(_clock.Now.AddTimeSpan(Config.SirenAlarm), true));

                await _mediator.Publish(new SendRichPushNotificationCommand
                {
                    Title    = sensorDetails.Title,
                    Body     = "Outdoor ALARM",
                    CameraId = sensorDetails.CameraId
                });
            }

            if (sensor.IsFrontDoor())
            {
                var strobeOn = "OFF";
                if (SensorArmed(Sensor.FrontDoorMotion))
                {
                    Log.Information($"[ALARMSTATE] TRIPPED Sensor: {sensor}");
                    TrippedSensors.Add(sensor);

                    _relayBoard.On(Enums.Relay.AlarmStrobe);

                    _timerEvents.UpdateEvent(Enums.TimedEvent.StrobeOff, new TimedEvent(_clock.Now.AddTimeSpan(Config.StrobeAlarm), true));

                    strobeOn = "ON";
                }

                await _mediator.Publish(new SendRichPushNotificationCommand
                {
                    Title    = sensorDetails.Title,
                    Body     = $"Alarm strobe is {strobeOn}",
                    CameraId = sensorDetails.CameraId
                });
            }

            if (sensor.IsGarageDoor())
            {
                Log.Information($"[ALARMSTATE] TRIPPED Sensor: {sensor}");
                TrippedSensors.Add(sensor);

                _relayBoard
                .Relay(Enums.Relay.AlarmStrobe)
                .Relay(Enums.Relay.AlarmSiren)
                .On();

                _timerEvents.UpdateEvent(Enums.TimedEvent.StrobeOff, new TimedEvent(_clock.Now.AddTimeSpan(Config.StrobeAlarm), true));
                _timerEvents.UpdateEvent(Enums.TimedEvent.SirenOff, new TimedEvent(_clock.Now.AddTimeSpan(Config.SirenAlarm), true));

                await _mediator.Publish(new SendRichPushNotificationCommand
                {
                    Title    = sensorDetails.Title,
                    Body     = "Alarm ACTIVATED",
                    CameraId = sensorDetails.CameraId
                });
            }

            void TurnLightsOnAtNight()
            {
                if (Config.ArmedState.ArmedAwayNight || Config.ArmedState.ArmedSleeping)
                {
                    _relayBoard
                    .Relay(Enums.Relay.LightsGarden)
                    .On();
                }
            }
        }