/// <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}"); }
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); } } } } }
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); }
/// <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"); } }
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); } } } }
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 }