Example #1
0
        /// <inheritdoc />
        protected override void OnStart(string[] args)
        {
            var port        = Settings.Default.Port;
            var url         = Environment.UserInteractive ? $"http://localhost:{port}/" : $"http://+:{port}/";
            var readableUrl = url.Replace("+", Environment.MachineName);

            Console.Write("Starting API at ");
            Console.BackgroundColor = ConsoleColor.DarkBlue;
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.WriteLine(readableUrl);
            Console.BackgroundColor = ConsoleColor.Black;
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine();
            Console.WriteLine();
            _api                     = WebApp.Start <Startup>(url);
            _logging                 = ObjectFactory.GetInstance <ILogging>();
            _executor                = ObjectFactory.GetInstance <IExecutor>();
            _timeProvider            = ObjectFactory.GetInstance <ITimeProvider>();
            _healthCounterRepository = ObjectFactory.GetInstance <IHealthCounterRepository>();
            _timer                   = new System.Timers.Timer()
            {
                Interval  = TimeSpan.FromSeconds(10).TotalMilliseconds,
                Enabled   = true,
                AutoReset = false,
            };
            _timer.Elapsed += this.Pulse;

            _logging.LogDebug($"Service OnStart done. API started at {readableUrl}");
        }
Example #2
0
        public bool TriggerTrue(List <DeviceValue> dataPoints, AscDescEnum ascDesc, double thresholdValue, int numberOfLastMeasurements)
        {
            if (dataPoints == null || dataPoints.Count < 2)
            {
                _logging.LogDebug("Datapoints is null or has not minimum number of items (2) for finding curve");
                return(false);
            }

            //if (dataPoints.Count < numberOfLastMeasurements)
            //{
            //    _logging.LogDebug($"Too few datapoints compared to set value in trigger: Number of data points: {dataPoints.Count}, number of data points to use: {numberOfLastMeasurements}");
            //    return false;
            //}

            //Get last data point
            var lastDataPoint = dataPoints.OrderBy(x => x.DateTimeOfMeasurment).Last();

            //Check if we have reached threshold. If not return false
            if (!ThresholdReached(ascDesc, lastDataPoint.Value, thresholdValue))
            {
                return(false);
            }

            var resultSetComputedLinearData = CreateLinearDataSet(dataPoints, numberOfLastMeasurements);

            return(CheckResultData(ascDesc, resultSetComputedLinearData));
        }
        public StorageHandler(ILogging logging, IIniSettings iniSettings, string dbPath = null)
        {
            _logging     = logging;
            _iniSettings = iniSettings;
            var fullPathToDb = CreateDbPath();

            if (!string.IsNullOrEmpty(dbPath))
            {
                fullPathToDb = dbPath;
            }

            _pathToRepo = fullPathToDb;

            if (File.Exists(fullPathToDb))
            {
                return;
            }
            _logging.LogDebug("Creating folder for liteDb database");
            var dbDirectory = Path.GetDirectoryName(fullPathToDb);

            if (dbDirectory != null)
            {
                Directory.CreateDirectory(dbDirectory);
            }
        }
        public IEnumerable <WeatherForecast> Get()
        {
            _logging.LogDebug($"[{typeof(WeatherForecastController).FullName} - {MethodBase.GetCurrentMethod().Name}] - (Se realiza loggeo " +
                              $"satisfactoriamente)");

            _logging.LogError($"[{typeof(WeatherForecastController).FullName} - {MethodBase.GetCurrentMethod().Name}] - (Se realiza loggeo " +
                              $"satisfactoriamente)");

            _logging.LogFatal($"[{typeof(WeatherForecastController).FullName} - {MethodBase.GetCurrentMethod().Name}] - (Se realiza loggeo " +
                              $"satisfactoriamente)");

            _logging.LogInfo($"[{typeof(WeatherForecastController).FullName} - {MethodBase.GetCurrentMethod().Name}] - (Se realiza loggeo " +
                             $"satisfactoriamente)");

            _logging.LogWarn($"[{typeof(WeatherForecastController).FullName} - {MethodBase.GetCurrentMethod().Name}] - (Se realiza loggeo " +
                             $"satisfactoriamente)");

            var rng = new Random();

            return(Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
                   .ToArray());
        }
        public TriggerHandler(IHSApplication hs, IAppCallbackAPI callback, IIniSettings iniSettings,
                              ILogging logging, IHsCollectionFactory collectionFactory, IHomeSeerHandler homeSeerHandler, IStorageHandler storageHandler)
        {
            _hs                = hs;
            _callback          = callback;
            _iniSettings       = iniSettings;
            _logging           = logging;
            _collectionFactory = collectionFactory;
            _homeSeerHandler   = homeSeerHandler;
            _storageHandler    = storageHandler;
            _logging.LogDebug("Creating trigger types");
            _triggerTypes = CreateTriggerTypes();

            _logging.LogDebug("Starting thread to fetch triggers");
            GetPluginTriggersFromHomeSeerInNewThread();

            _logging.LogDebug("Done init TriggerHandler");
        }
        public void AddDeviceValueToDatabase(double value, DateTime dateTimeOfMeasurement, int referenceId)
        {
            using (var db = new LiteDatabase(_pathToRepo))
            {
                var deviceValues = db.GetCollection <DeviceValue>(DeviceValuesTable);
                _logging.LogDebug("LiteDbRepo: inserting value into liteDb");
                deviceValues.Insert(new DeviceValue()
                {
                    DeviceId = referenceId, Value = value, DateTimeOfMeasurment = dateTimeOfMeasurement
                });
                deviceValues.EnsureIndex(x => x.DateTimeOfMeasurment);
                deviceValues.EnsureIndex(x => x.DeviceId);
            }

            if (SystemDateTime.Now().Hour == 0)
            {
                lock (_lockObject)
                {
                    using (var db = new LiteDatabase(_pathToRepo))
                    {
                        var storageMaintenanceValues = db.GetCollection <StorageMaintenance>(StorageMaintenanceTable);
                        var lastMaintenanceDone      =
                            storageMaintenanceValues.Exists(
                                Query.EQ("DateTimeOfMaintenance", SystemDateTime.Now().Date));
                        if (!lastMaintenanceDone)
                        {
                            DeleteAllValuesOlderThanSetNumberOfDays(db);
                            //Run maintenance

                            //Insert record for done maintenance
                            storageMaintenanceValues.Insert(new StorageMaintenance()
                            {
                                DateTimeOfMaintenance = SystemDateTime.Now().Date
                            });
                            storageMaintenanceValues.EnsureIndex(x => x.DateTimeOfMaintenance);
                        }
                    }
                }
            }
        }
Example #7
0
        public bool TriggerTrue(List <DeviceValue> dataPoints, AscDescEnum ascDesc, double?threshold = null, TimeSpan?timeToReachThreshold = null)
        {
            if (dataPoints != null && dataPoints.Count > 1)
            {
                _logging.LogDebug($"Wait for lock in DataCurveComputation for device:{dataPoints.First().DeviceId}");

                //Do computations to find if we have ascending or descending curve. Start by locking the methode to avoid multiple results
                lock (_lock)
                {
                    _logging.LogDebug($"computing the curve for device:{dataPoints.First().DeviceId}");

                    var fitLineHandler = new FitLineHandler();
                    var resultSetComputedLinearData = fitLineHandler.ComputeLinearData(dataPoints);

                    var culture = CultureInfo.CreateSpecificCulture("en-US");
                    _logging.LogDebug($"result of computing IsDescending: {resultSetComputedLinearData.IsDescending.ToString()} IsAscending:{resultSetComputedLinearData.IsAscending.ToString()} Slope:{resultSetComputedLinearData.Slope.ToString("#.###", culture)}");

                    var resultsetLastValues = ComputeLastValues(dataPoints, ascDesc);

                    if (threshold.HasValue && timeToReachThreshold.HasValue)
                    {
                        //Hente ut siste verdi
                        var resultSetComputedFutureLine = ComputeFutureValues(dataPoints, ascDesc, resultSetComputedLinearData, threshold.Value, timeToReachThreshold.Value);
                        _logging.LogDebug($"ascDec Descending{ascDesc == AscDescEnum.Descending} resultSetComputedFutureLine.TriggerTrue: {resultSetComputedFutureLine.TriggerTrue} resultSetComputedLinearData.IsDescending: {resultSetComputedLinearData.IsDescending } resultSetComputedLinearData.IsAscending: {resultSetComputedLinearData.IsAscending }  resultsetLastValues.LastSlope: {resultsetLastValues.LastSlope} resultsetLastValues.LastValueHighest: {resultsetLastValues.LastValueHighest } resultsetLastValues.LastValueLowest: {resultsetLastValues.LastValueLowest} ");
                        if (ascDesc == AscDescEnum.Ascending && resultSetComputedFutureLine.TriggerTrue && resultSetComputedLinearData.IsAscending && resultsetLastValues.LastSlope > 0 && resultsetLastValues.LastValueHighest)
                        {
                            return(true);
                        }
                        if (ascDesc == AscDescEnum.Descending && resultSetComputedFutureLine.TriggerTrue && resultSetComputedLinearData.IsDescending && resultsetLastValues.LastSlope < 0 && resultsetLastValues.LastValueLowest)
                        {
                            return(true);
                        }
                    }

                    else
                    {
                        //Only test curves
                        _logging.LogDebug($"ascDec Descending{ascDesc == AscDescEnum.Descending}  resultSetComputedLinearData.IsDescending: {resultSetComputedLinearData.IsDescending } resultSetComputedLinearData.IsAscending: {resultSetComputedLinearData.IsAscending }  resultsetLastValues.LastSlope: {resultsetLastValues.LastSlope} resultsetLastValues.LastValueHighest: {resultsetLastValues.LastValueHighest } resultsetLastValues.LastValueLowest: {resultsetLastValues.LastValueLowest} ");
                        if (ascDesc == AscDescEnum.Ascending && resultSetComputedLinearData.IsAscending && resultsetLastValues.LastSlope > 0 && resultsetLastValues.LastValueHighest)
                        {
                            return(true);
                        }
                        if (ascDesc == AscDescEnum.Descending && resultSetComputedLinearData.IsDescending && resultsetLastValues.LastSlope < 0 && resultsetLastValues.LastValueLowest)
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Example #8
0
 /// <inheritdoc />
 protected override void OnStop()
 {
     _logging.LogDebug("Service stopped.");
     _timer?.Dispose();
     _executor?.Dispose();
     try
     {
         if (_api != null)
         {
             //TODO: find out how to dispose webapp
             // Structure map ioc is buggy and will throw an exception
             // see: https://github.com/WebApiContrib/WebApiContrib.IoC.StructureMap/commit/d0306db2169303f3fdb56a7c7ac940207b5cf0c2
             // Nuget has not been updated since 2012. switch to submodule, or ignore.
             //_api.Dispose();
         }
     }
     catch (Exception e)
     {
         _logging.LogException(e, "Failed to dispose webapp");
     }
 }
Example #9
0
 public void HsEvent(Enums.HSEvent eventType, object[] parameters)
 {
     //Catch changes to values and store them for the devices we are watching
     _numberOfEventsReceived++;
     if (eventType == Enums.HSEvent.VALUE_CHANGE)
     {
         //_logging.LogDebug("Got an value changed event. Trying to check if we should store it");
         _numberOfValueChanngeEventsReceived++;
         if (parameters != null && parameters.Length > 4 && parameters[2] != null && parameters[4] != null &&
             parameters[2] is double && parameters[4] is int)
         {
             var newValue = (double)parameters[2];
             var deviceId = (int)parameters[4];
             //Console.WriteLine($"Something happened to a value for deviceId {deviceId} (value: {newValue.ToString()})");
             if (DeviceIsWatched(deviceId))
             {
                 _logging.LogDebug($"logging an event with data deviceId:{deviceId} value: {newValue}");
                 _numberOfEventsStored++;
                 _storageHandler.AddDeviceValueToDatabase(newValue, DateTime.Now, deviceId);
             }
         }
     }
 }
Example #10
0
        public void Pulse()
        {
            lock (_jobRepository)
            {
                #region semaphore
                string currentOwner;
                var    firstCallAfterSemaphore = _firstPulse || !_wasMaster;
                if (!_semaphoreRepository.Get(nameof(Executor), Utilities.GetCallerId(), out currentOwner))
                {
                    if (_firstPulse)
                    {
                        _logging.LogInfo($"Did not get semaphore, current owner : {currentOwner}. Will stand by as slave.");
                        _firstPulse = false;
                    }
                    else if (_wasMaster)
                    {
                        _logging.LogWarning($"Lost semaphore to : {currentOwner}. Will stand by as slave.");
                        _wasMaster = false;
                    }
                    return;
                }
                if (_firstPulse)
                {
                    _logging.LogInfo($"Got semaphore, as : {currentOwner}. Will work as master.");
                    _firstPulse = false;
                }
                else if (!_wasMaster)
                {
                    _logging.LogInfo($"Slave woken, {currentOwner} is now owner. Will work as master.");
                    foreach (var plugin in _plugins)
                    {
                        plugin.Reset();
                    }
                }
                _wasMaster = true;
                #endregion

                #region command
                foreach (var command in _commandRepository.GetAll())
                {
                    // ReSharper disable once SwitchStatementMissingSomeCases
                    switch (command.Type)
                    {
                    case CommandType.Cancel:
                        CancelJob(command.Urn, command.Username);
                        break;

                    default:
                        _logging.LogWarning($"Command state {command.Type} is not implemented.", command.Urn);
                        break;
                    }
                    _commandRepository.Remove(command);
                }
                #endregion

                #region planner
                // TODO: modify existing plans ? :hamburger: :+1:
                if (!firstCallAfterSemaphore) // skip first pulse to reassign in-progress tasks to plugins.
                {
                    _planner.Calculate();
                }
                #endregion

                #region jobs, task and plugins
                foreach (var job in _jobRepository.ActiveJobs().ToList())
                {
                    //TODO: Add support for cancel

                    var plan = job.Plan;
startOfJobLoop:
                    var executionTask = plan.GetCurrentTask();
                    var targetPlugin = _plugins.First(p => p.Urn == executionTask.PluginUrn);
                    switch (executionTask.State)
                    {
                    case ExecutionState.Queued:
                        if (targetPlugin.Busy)
                        {
                            // TODO: log planning warning
                            break;
                        }
                        _logging.LogDebug($"Task {executionTask.Urn} assigned to {targetPlugin.Urn}.", job.Urn);
                        targetPlugin.Assign(executionTask);
                        goto case ExecutionState.Running;

                    case ExecutionState.Running:
                        targetPlugin.Pulse(executionTask);
                        if (executionTask.State == ExecutionState.Done)
                        {
                            goto case ExecutionState.Done;
                        }
                        if (executionTask.State == ExecutionState.Failed)
                        {
                            goto case ExecutionState.Failed;
                        }
                        plan.Tasks[plan.ActiveTaskIndex.Value] = executionTask;
                        break;

                    case ExecutionState.Done:
                        _logging.LogDebug($"Task {executionTask.Urn} done, released from {targetPlugin.Urn}.", job.Urn);
                        targetPlugin.Release(executionTask);
                        plan.Tasks[plan.ActiveTaskIndex.Value] = executionTask;
                        plan.MoveToNextTask();
                        if (plan.ActiveTaskIndex.HasValue) // has more tasks
                        {
                            _jobRepository.Update(job);    // save and...
                            goto startOfJobLoop;           //start next task at once
                        }
                        break;

                    case ExecutionState.Failed:
                        if (targetPlugin.CanRetry && executionTask.NumberOfRetries < targetPlugin.RetryMax)
                        {
                            targetPlugin.Retry(executionTask);
                        }
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    if (plan.GetState() == ExecutionState.Done)
                    {
                        job.Destination = plan.GetCurrentEssence();
                        job.EndTime     = _timeProvider.GetUtcNow();
                        _logging.LogInfo("Job done", job.Urn);
                    }

                    if (plan.GetState() == ExecutionState.Failed)
                    {
                        _logging.LogWarning("Job failed", job.Urn);
                    }


                    if ((plan.GetState() == ExecutionState.Failed || plan.GetState() == ExecutionState.Done) && !string.IsNullOrEmpty(job.CallbackUrl))
                    {
                        MakeCallback(job);
                    }
                    _jobRepository.Update(job);
                }
            }
            #endregion
        }