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