Ejemplo n.º 1
0
        // 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);
                }
            }
        }