public async Task GetBlindConsumption() { while (true) { Service service = db.Services.Find(7); // Maak een nieuwe servicerun aan ServiceRun serviceRun = new ServiceRun { iServiceKey = 7, dtServiceRunStartDate = DateTime.UtcNow, ServiceRunErrors = new List <ServiceRunError>() }; try { DateTime today = DateTime.Now; // Haal nieuwe accessToken op als de oude verlopen is if (today.AddMinutes(-10) >= FuduraExpiredDate) { GetFuduraAccessToken(); } // Haal alle meters van fudura op die gekoppeld zijn aan een adres en metertype inkoop/distributie/verkoop elektra of gas hebben hebben List <ConsumptionMeter> consumptionMeters = db.ConsumptionMeters .Include(i => i.Counters) .Include(i => i.Counters.Select(s => s.BlindConsumption)) .Where(w => w.iConsumptionMeterSupplierKey == 2 && w.iAddressKey != null && w.Counters.Any(u => u.iCounterTypeKey == 15)) .ToList(); foreach (ConsumptionMeter consumptionMeter in consumptionMeters) { try { DateTime authorizedFromDate = GetFuduraConsumptionMeterAuthorizedFrom(consumptionMeter.sEANCode); DateTime firstPickUpMonth = authorizedFromDate < new DateTime(2016, 1, 1) ? new DateTime(2016, 1, 1) : authorizedFromDate; DateTime lastAvailableDate = GetFuduraLastAvailableData(consumptionMeter.sEANCode); // Haal de blindverbruiksmeter op bij de meter Counter blindConsumptionCounter = consumptionMeter.Counters.FirstOrDefault(f => f.iCounterTypeKey == 15); if (blindConsumptionCounter == null) { throw new Exception(string.Format("Er is geen telwerk gevonden voor het meten van blindverbruik bij meter met EANCode {0}", consumptionMeter.sEANCode)); } // Haal het laatst geregistreerd blindverbruik van het telwerk op BlindConsumption lastRegisteredBlindConsumption = blindConsumptionCounter.BlindConsumption.OrderByDescending(o => o.dtEndDateTime).FirstOrDefault(); if (lastRegisteredBlindConsumption != null) { firstPickUpMonth = lastRegisteredBlindConsumption.dtEndDateTime; } if (firstPickUpMonth <= today.AddMonths(-1)) { decimal dBlindConsumption = 0; WebClient client = new WebClient { Encoding = Encoding.UTF8 }; client.Headers.Add(HttpRequestHeader.Authorization, "bearer " + FuduraAccessToken); client.Headers.Add("Content-type", "application/json"); DateTime firstPickUpDayOfMonth = new DateTime(firstPickUpMonth.Year, firstPickUpMonth.Month, 1); string urlChannels = string.Format("{0}/aansluitingen/{1}/channels/E65_EMVLRx/datapoints/{2}/{3}/{4}", apiFuduraEndPoint, consumptionMeter.sEANCode, firstPickUpMonth.Year, firstPickUpMonth.Month, firstPickUpMonth.Day); string result = client.DownloadString(urlChannels); JArray jsonArray = JArray.Parse(result); foreach (JToken item in jsonArray) { DateTime itemStartDateTime = DateTime.Parse(item["From"].ToString()); DateTime itemEndDateTime = DateTime.Parse(item["To"].ToString()); dBlindConsumption = decimal.Parse(item["ReadingN"].ToString()); if (blindConsumptionCounter.BlindConsumption.Count() != 0) { if (itemStartDateTime > blindConsumptionCounter.BlindConsumption.OrderByDescending(o => o.dtEndDateTime).FirstOrDefault().dtStartDateTime) { BlindConsumption blindConsumption = new BlindConsumption { iAddressKey = consumptionMeter.iAddressKey.Value, Counter = blindConsumptionCounter, dtStartDateTime = itemStartDateTime, dtEndDateTime = itemEndDateTime, dBlindConsumption = dBlindConsumption, ServiceRun = serviceRun }; blindConsumptionCounter.BlindConsumption.Add(blindConsumption); } } else { BlindConsumption blindConsumption = new BlindConsumption { iAddressKey = consumptionMeter.iAddressKey.Value, Counter = blindConsumptionCounter, dtStartDateTime = itemStartDateTime, dtEndDateTime = itemEndDateTime, dBlindConsumption = dBlindConsumption, ServiceRun = serviceRun }; blindConsumptionCounter.BlindConsumption.Add(blindConsumption); } } } } catch (Exception e) { ServiceRunError error = new ServiceRunError { sConsumptionMeterNumber = consumptionMeter.sConsumptionMeterNumber, sErrorMessage = e.Message, iStatusCode = 500, ServiceRun = serviceRun, dtEffectiveDateTime = DateTime.UtcNow }; serviceRun.ServiceRunErrors.Add(error); ServiceRun.iServiceRunStatus = 500; } } int rowsAdded = db.ChangeTracker.Entries().Count(c => c.State == EntityState.Added); serviceRun.dtServiceRunEndDate = DateTime.UtcNow; serviceRun.sServiceRunMessage = rowsAdded + " row(s) added at BlindConsumption."; serviceRun.iServiceRunRowsUpdated = rowsAdded; serviceRun.iServiceRunStatus = serviceRun.ServiceRunErrors.Count > 0 || serviceRun.iServiceRunStatus == 500 ? 500 : 200; if (rowsAdded > 0) { db.ServiceRuns.Add(serviceRun); } db.SaveChanges(); DateTime now = DateTime.Now; DateTime startDate = new DateTime(now.AddMonths(1).Year, now.AddMonths(1).Month, 1).Date.AddHours(5); service.dtNextServiceRun = TimeZoneInfo.ConvertTimeToUtc(startDate, TimeZoneInfo.Local); db.Entry(service).State = EntityState.Modified; db.SaveChanges(); TimeSpan interval = startDate - now; await Task.Delay(interval); } catch (Exception e) { serviceRun.dtServiceRunEndDate = DateTime.UtcNow; serviceRun.sServiceRunMessage = e.Message; serviceRun.iServiceRunStatus = 500; serviceRun.iServiceRunRowsUpdated = 0; db.ServiceRuns.Add(serviceRun); db.SaveChanges(); DateTime now = DateTime.Now; DateTime startDate = now.AddDays(1).Date.AddHours(5); service.dtNextServiceRun = TimeZoneInfo.ConvertTimeToUtc(startDate, TimeZoneInfo.Local); db.Entry(service).State = EntityState.Modified; db.SaveChanges(); TimeSpan interval = startDate - now; await Task.Delay(interval); } } }
//public List<MaximumPower> MaximumPowers { get; set; } #endregion #region Methods public async Task <ServiceRun> GetMeterConsumption(int consumptionMeterKey, ServiceRun serviceRun) { ConsumptionMeter consumptionMeter = await db.ConsumptionMeters.Include(i => i.Counters).FirstOrDefaultAsync(f => f.iConsumptionMeterKey == consumptionMeterKey); if (consumptionMeter.Counters.Count == 0) { serviceRun.ServiceRunErrors.Add(new ServiceRunError { dtEffectiveDateTime = DateTime.UtcNow, iStatusCode = (int)HttpStatusCode.NotFound, sConsumptionMeterNumber = consumptionMeter.sConsumptionMeterNumber, sErrorMessage = string.Format("Er zijn nog geen telwerken gevonden voor de meter met EANCode {0}", consumptionMeter.sEANCode), sProjectNumber = consumptionMeter.Address.Project.ProjectBase.sProjectCode }); return(serviceRun); } DateTime today = DateTime.Today; DateTime authorizedFromDate = _fuduraService.GetAuthorizedDateFrom(consumptionMeter.sEANCode); List <Consumption> consumptionList = new List <Consumption>(); try { foreach (Counter counter in consumptionMeter.Counters.Where(w => !new[] { 11, 14, 15 }.Contains(w.iCounterTypeKey))) { Consumption lastConsumption = db.Consumption.Where(w => w.iCounterKey == counter.iCounterKey).OrderByDescending(o => o.dtEndDateTime).ThenByDescending(t => t.dEndPosition).FirstOrDefault(); if (lastConsumption == null) { serviceRun.ServiceRunErrors.Add(new ServiceRunError { dtEffectiveDateTime = DateTime.UtcNow, iStatusCode = (int)HttpStatusCode.NotFound, sConsumptionMeterNumber = consumptionMeter.sConsumptionMeterNumber, sErrorMessage = string.Format("Voor telwerk {0} is geen verbruiksregel geregistreerd.", counter.sCounterCode), sProjectNumber = consumptionMeter.Address.Project.ProjectBase.sProjectCode }); return(serviceRun); } // Wat is de laatste datum in db van het verbruik DateTime firstPickUpDay = lastConsumption.dtEndDateTime; if (firstPickUpDay < authorizedFromDate) { serviceRun.ServiceRunErrors.Add(new ServiceRunError { dtEffectiveDateTime = DateTime.UtcNow, iStatusCode = (int)HttpStatusCode.NotFound, sConsumptionMeterNumber = consumptionMeter.sConsumptionMeterNumber, sErrorMessage = string.Format("Meter {0} is geauthorizeerd vanaf {1} en er wordt geprobeerd data op te halen vanaf {2}.", consumptionMeter.sEANCode, authorizedFromDate.Date, firstPickUpDay.Date), sProjectNumber = consumptionMeter.Address.Project.ProjectBase.sProjectCode }); return(serviceRun); } // Haal de laatste beschikbare datum op uit de webservice DateTime lastAvailableData = _fuduraService.GetLastAvailableData(consumptionMeter.sEANCode); // Check of onze db meter hetzelfde meet als de meter uit de api switch (counter.iCounterTypeKey) { case 1: // Check of ws ook Elektra meet if (_fuduraService.ProductType != "E") { serviceRun.ServiceRunErrors.Add(new ServiceRunError { dtEffectiveDateTime = DateTime.UtcNow, iStatusCode = (int)HttpStatusCode.NotFound, sConsumptionMeterNumber = consumptionMeter.sConsumptionMeterNumber, sErrorMessage = string.Format("Vanuit Database verwachten we bij teller {1} voor elektra en we krijgen nu een meter die {0} meet.", _fuduraService.ProductType, counter.iCounterKey), sProjectNumber = consumptionMeter.Address.Project.ProjectBase.sProjectCode }); return(serviceRun); } break; case 2: // Check of ws ook Gas meet if (_fuduraService.ProductType != "G") { serviceRun.ServiceRunErrors.Add(new ServiceRunError { dtEffectiveDateTime = DateTime.UtcNow, iStatusCode = (int)HttpStatusCode.NotFound, sConsumptionMeterNumber = consumptionMeter.sConsumptionMeterNumber, sErrorMessage = string.Format("Vanuit Database verwachten we bij teller {1} voor gas en we krijgen nu een meter die {0} meet.", _fuduraService.ProductType, counter.iCounterKey), sProjectNumber = consumptionMeter.Address.Project.ProjectBase.sProjectCode }); return(serviceRun); } break; case 3: // Check of ws ook Elektra meet if (_fuduraService.ProductType != "E") { serviceRun.ServiceRunErrors.Add(new ServiceRunError { dtEffectiveDateTime = DateTime.UtcNow, iStatusCode = (int)HttpStatusCode.NotFound, sConsumptionMeterNumber = consumptionMeter.sConsumptionMeterNumber, sErrorMessage = string.Format("Vanuit Database verwachten we bij teller {1} voor elektra en we krijgen nu een meter die {0} meet.", _fuduraService.ProductType, counter.iCounterKey), sProjectNumber = consumptionMeter.Address.Project.ProjectBase.sProjectCode }); return(serviceRun); } break; case 4: // Check of ws ook Elektra meet if (_fuduraService.ProductType != "E") { serviceRun.ServiceRunErrors.Add(new ServiceRunError { dtEffectiveDateTime = DateTime.UtcNow, iStatusCode = (int)HttpStatusCode.NotFound, sConsumptionMeterNumber = consumptionMeter.sConsumptionMeterNumber, sErrorMessage = string.Format("Vanuit Database verwachten we bij teller {1} voor elektra en we krijgen nu een meter die {0} meet.", _fuduraService.ProductType, counter.iCounterKey), sProjectNumber = consumptionMeter.Address.Project.ProjectBase.sProjectCode }); return(serviceRun); } break; } // Check tot welke datum opgehaald moet worden (vandaag of laatste registratiedatum) DateTime lastPickUpDateTime = lastAvailableData < today ? lastAvailableData : today.Date; TimeSpan timeSpan = lastPickUpDateTime - firstPickUpDay; DateTime consumptionStart = firstPickUpDay; for (int i = 0; i <= timeSpan.Days; i++) { //DateTime pickUpDay = firstPickUpDay.AddDays(i); DateTime pickUpDay = consumptionStart; decimal usage = 0; DateTime consumptionDateTime = pickUpDay.Date; string resultString = _fuduraService.GetTimeSeries(consumptionMeter.sEANCode, consumptionDateTime); if (!string.IsNullOrEmpty(resultString)) { JArray jsonArray = JArray.Parse(resultString); bool saveConsumption = false; foreach (JToken consumption in jsonArray) { //Voeg pas verbruik toe als de datum hoger is dan laatste datum in db if (consumptionDateTime >= pickUpDay) { saveConsumption = true; switch (counter.iCounterTypeKey) { case 3: usage = usage + decimal.Parse(consumption["ReadingL"].ToString()); break; default: usage = usage + decimal.Parse(consumption["ReadingN"].ToString()); break; } } consumptionDateTime = DateTime.Parse(consumption["Timestamp"].ToString()); } Consumption previousConsumption = consumptionList.Where(w => w.Counter == counter).OrderByDescending(o => o.dtEndDateTime).FirstOrDefault() != null?consumptionList.Where(w => w.Counter == counter).OrderByDescending(o => o.dtEndDateTime).FirstOrDefault() : lastConsumption; Consumption newConsumption = new Consumption { iAddressKey = counter.ConsumptionMeter.iAddressKey.Value, Counter = counter, ServiceRun = serviceRun, dtStartDateTime = consumptionStart, dtEndDateTime = consumptionDateTime, dConsumption = usage, dEndPosition = previousConsumption.dEndPosition + usage, bExcludeForReport = counter.ConsumptionMeter.MeterType.sPurchaseOrSale.Contains("Distribution"), bValidated = true }; if (saveConsumption) { consumptionList.Add(newConsumption); } consumptionStart = consumptionDateTime; } consumptionStart = consumptionStart.AddDays(1).Date; } // End of for all days } // End of foreach counter serviceRun.iServiceRunRowsUpdated += consumptionList.Count; db.Consumption.AddRange(consumptionList); await db.SaveChangesAsync(); return(await Task.FromResult(serviceRun)); } catch (Exception e) { ServiceRunError error = new ServiceRunError { dtEffectiveDateTime = DateTime.UtcNow, iStatusCode = 500, sConsumptionMeterNumber = consumptionMeter.sConsumptionMeterNumber, sErrorMessage = e.Message, ServiceRun = serviceRun }; serviceRun.ServiceRunErrors.Add(error); serviceRun.iServiceRunStatus = 500; return(await Task.FromResult(serviceRun)); } // Loop elk telwerk af }
// Get all Consumption From SDS Api en save it in the database public async Task GetSDSConsumption() { while (true) { Service service = db.Services.Find(1); // Maak een nieuwe serviceRun aan ServiceRun serviceRun = new ServiceRun { iServiceKey = service.iServiceKey, dtServiceRunStartDate = DateTime.UtcNow, ServiceRunErrors = new List <ServiceRunError>() }; // Maak een lege lijst aan waarin vervolgens het verbruik in gestopt kan worden List <Consumption> consumptionList = new List <Consumption>(); // Deze Hashset lijst wordt gebruikt om het al aanwezige verbruik toe te voege HashSet <Consumption> existedConsumptionList = new HashSet <Consumption>(); try { // Pak de huidige datum DateTime today = DateTime.Now; // Haal alle meters en telwerken op van de meters van SDS die aan een adres gekoppeld zijn. var currentConsumptionMeters = db.ConsumptionMeters .Include(i => i.Counters) .Where(w => w.iConsumptionMeterSupplierKey == 1 && w.iAddressKey != null).ToList(); //Draai een loop af voor elke meter foreach (ConsumptionMeter meter in currentConsumptionMeters) //foreach (ConsumptionMeter meter in currentConsumptionMeters) { // Check of consumptionMeter exist in API SmartDataSolution _sds = new SmartDataSolution(); if (await _sds.ConsumptionMeterExists(meter.sEANCode)) { // Check of de meter ook telwerken heeft if (meter.Counters.Count == 0) { throw new Exception(string.Format("Er zijn nog geen telwerken gevonden voor de meter met EANCode {0}", meter.sEANCode)); } // Haal de eerste beschikbare datum op van de meter DateTime dataAvailableFromDate = GetSDSConsumptionMeterAvailableFrom(meter.sEANCode); if (dataAvailableFromDate != new DateTime()) { // Loop elk telwerk af foreach (Counter counter in meter.Counters.Where(w => new int[] { 2, 3, 4 }.Contains(w.iCounterTypeKey))) { Consumption lastConsumption = db.Consumption.Where(w => w.iCounterKey == counter.iCounterKey).OrderByDescending(o => o.dtEndDateTime).ThenByDescending(t => t.dEndPosition).FirstOrDefault(); if (lastConsumption == null) { throw new Exception(string.Format("Voor telwerk {0} is geen verbruiksregel geregistreerd.", string.Join(", ", counter.sCounterCode))); } // Voeg de regel toe aan de HashSet existedConsumptionList.Add(lastConsumption); // Wat is de laatste datum van het verbruik DateTime firstPickUpDay = lastConsumption.dtEndDateTime; if (firstPickUpDay < dataAvailableFromDate) { throw new Exception(string.Format("Meter {0} is geauthorizeerd vanaf {1} en er wordt geprobeerd data op te halen vanaf {2}.", meter.sEANCode, dataAvailableFromDate.Date, firstPickUpDay.Date)); } // Haal laatst beschikbare datum op uit de webservice DateTime lastAvailableData = GetSDSLastAvailableData(meter.sEANCode); switch (counter.iCounterTypeKey) { case 1: //Check of ws ook elektra meet if (AssetType != "P4Electricity") { throw new Exception(string.Format("Vanuit Database verwachten we bij teller {1} voor elektra en we krijgen nu een meter die {0} meet.", AssetType, counter.iCounterKey)); } break; case 2: //Check of ws ook gas meet if (AssetType != "P4Gas") { throw new Exception(string.Format("Vanuit Database verwachten we bij teller {1} voor elektra en we krijgen nu een meter die {0} meet.", AssetType, counter.iCounterKey)); } break; case 3: //Check of ws ook elektra meet if (AssetType != "P4Electricity") { throw new Exception(string.Format("Vanuit Database verwachten we bij teller {1} voor elektra en we krijgen nu een meter die {0} meet.", AssetType, counter.iCounterKey)); } break; case 4: //Check of ws ook elektra meet if (AssetType != "P4Electricity") { throw new Exception(string.Format("Vanuit Database verwachten we bij teller {1} voor elektra en we krijgen nu een meter die {0} meet.", AssetType, counter.iCounterKey)); } break; } // Check tot welke datum opgehaald moet worden (vandaag of laatste registratiedatum) DateTime lastPickUpDateTime = lastAvailableData < today ? lastAvailableData : today.Date; TimeSpan timeSpan = lastPickUpDateTime - firstPickUpDay; string urlConsumption = string.Format("{0}readings/Identifier/{1}/Day/{2}?apikey={3}&dateto={4}&datetimeformat=nl&format=json&source=day", apiSDSEndPoint, meter.sEANCode, firstPickUpDay.ToString("yyyy-MM-dd"), SDSApiKey, lastPickUpDateTime.ToString("yyyy-MM-dd")); try { WebClient client = new WebClient { Encoding = Encoding.UTF8 }; string resultString = client.DownloadString(urlConsumption); JObject resultObject = JObject.Parse(resultString); JArray jsonArray = JArray.Parse(resultObject["Payload"].ToString()); foreach (JToken consumption in jsonArray) { Consumption previousConsumption = consumptionList.Where(w => w.Counter == counter).OrderByDescending(o => o.dtEndDateTime).FirstOrDefault() != null?consumptionList.Where(w => w.Counter == counter).OrderByDescending(o => o.dtEndDateTime).FirstOrDefault() : existedConsumptionList.Where(w => w.Counter == counter).OrderByDescending(o => o.dtEndDateTime).FirstOrDefault(); decimal ApiEndPosition = 0; switch (counter.iCounterTypeKey) { case 2: ApiEndPosition = decimal.Parse(consumption["R180"].ToString()); break; case 3: ApiEndPosition = decimal.Parse(consumption["R181"].ToString()); break; case 4: ApiEndPosition = decimal.Parse(consumption["R182"].ToString()); break; default: break; } DateTime consumptionDateTime = DateTime.Parse(consumption["DateTime"].ToString()); // Set the correctionfactor if (consumption == jsonArray.First) { counter.dCorrectionMutation = counter.dCorrectionMutation != 0 ? counter.dCorrectionMutation : previousConsumption.dEndPosition - ApiEndPosition; } else if (consumptionDateTime > previousConsumption.dtEndDateTime) { // Set correctionEndPosition ApiEndPosition = ApiEndPosition + counter.dCorrectionMutation; Consumption newConsumption = new Consumption { iAddressKey = counter.ConsumptionMeter.iAddressKey.Value, Counter = counter, ServiceRun = serviceRun, dtStartDateTime = previousConsumption.dtEndDateTime, dtEndDateTime = consumptionDateTime, dConsumption = ApiEndPosition - previousConsumption.dEndPosition, dEndPosition = ApiEndPosition, bExcludeForReport = counter.ConsumptionMeter.MeterType.sPurchaseOrSale.Contains("Distribution"), bValidated = true }; consumptionList.Add(newConsumption); } } } catch (Exception e) { ServiceRunError error = new ServiceRunError { dtEffectiveDateTime = DateTime.Now, iStatusCode = 500, sConsumptionMeterNumber = counter.ConsumptionMeter.sConsumptionMeterNumber, sErrorMessage = e.Message, ServiceRun = serviceRun }; serviceRun.ServiceRunErrors.Add(error); serviceRun.iServiceRunStatus = 500; } } // End of foreach counter } else { ServiceRunError error = new ServiceRunError { ServiceRun = serviceRun, dtEffectiveDateTime = DateTime.Now, iStatusCode = 500, sConsumptionMeterNumber = meter.sConsumptionMeterNumber, sErrorMessage = "Er kan geen data uit de API gelezen worden voor de meter" }; serviceRun.ServiceRunErrors.Add(error); serviceRun.iServiceRunStatus = 500; } } else { ServiceRunError serviceRunError = new ServiceRunError { iStatusCode = 500, sErrorMessage = string.Format("Meter met EAN-Code {0} kan niet gevonden worden in de API", meter.sEANCode), sConsumptionMeterNumber = meter.sConsumptionMeterNumber, ServiceRun = serviceRun, }; serviceRun.ServiceRunErrors.Add(serviceRunError); serviceRun.iServiceRunStatus = 500; } } // End of foreach meter //Voeg de hele lijst toe aan de database db.Consumption.AddRange(consumptionList); int rowsAdded = db.ChangeTracker.Entries().Count(c => c.State == EntityState.Added); serviceRun.dtServiceRunEndDate = DateTime.UtcNow; serviceRun.sServiceRunMessage = rowsAdded + " row(s) updated."; serviceRun.iServiceRunRowsUpdated = rowsAdded; serviceRun.iServiceRunStatus = serviceRun.iServiceRunStatus == 500 ? 500 : 200; if (rowsAdded > 0) { db.ServiceRuns.Add(serviceRun); } db.SaveChanges(); currentConsumptionMeters.Clear(); //Check invoeren over saldo van afgelopen dag/maand zelfde als ws if (today.Day == 1) { //Checks invoeren } DateTime now = DateTime.Now; DateTime startDate = now.AddDays(1).Date.AddHours(5); service.dtNextServiceRun = TimeZoneInfo.ConvertTimeToUtc(startDate, TimeZoneInfo.Local); db.Entry(service).State = EntityState.Modified; db.SaveChanges(); TimeSpan interval = startDate - now; await Task.Delay(interval); } catch (Exception e) { serviceRun.dtServiceRunEndDate = DateTime.UtcNow; serviceRun.sServiceRunMessage = e.Message; serviceRun.iServiceRunStatus = 500; serviceRun.iServiceRunRowsUpdated = 0; // Verwijder de lijst als aanpassingen hebben plaatsgevonden if (db.ChangeTracker.HasChanges()) { db.Consumption.RemoveRange(consumptionList); } db.ServiceRuns.Add(serviceRun); db.SaveChanges(); DateTime now = DateTime.Now; DateTime startDate = now.AddDays(1).Date.AddHours(5); service.dtNextServiceRun = TimeZoneInfo.ConvertTimeToUtc(startDate, TimeZoneInfo.Local); db.Entry(service).State = EntityState.Modified; db.SaveChanges(); TimeSpan interval = startDate - now; await Task.Delay(interval); } } }