Example #1
0
 public async Task<bool> StoreProbesIntervalAsync(ProbesInterval interval)
 {
     try { await GetIntervalsCollection().InsertOneAsync(interval); }
     catch (Exception ex)
     {
         Logger.Log(ex.Message);
         return false;
     }
     return true;
 }
Example #2
0
        /// <summary>
        /// This worker ask to the database for data to be processed
        /// Only data created before the 5 minutes of each loop are taken into account, the newers can be calculated in the next loop.
        /// If no data are avaible, the worker sleeps for one minute.
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private async Task InterpolationLoopAsync(CancellationToken token)
        {
            //Ottengo dal database l'ultimo intervallo salvato
            ProbesInterval last_interval = null;

            try
            {
                last_interval = await dbConnection.GetLastInterval();
            }
            catch
            {
                ShowErrorMessage("Database connection error.\nData Collection has been stopped");
                return;
            }
            if (last_interval is null)
            {
                while (true)
                {
                    last_interval = new ProbesInterval
                    {
                        Timestamp  = await dbConnection.GetFirstTimestamp(),
                        IntervalId = -1
                    };
                    if (last_interval.Timestamp == default)
                    {
                        Thread.Sleep(30000);
                        continue;
                    }
                    break;
                }
                last_interval.Timestamp = last_interval.Timestamp.AddSeconds(-last_interval.Timestamp.Second).AddMinutes(-1);
            }

            while (token.IsCancellationRequested is false)
            {
                if (DateTime.Compare(DateTime.Now, last_interval.Timestamp.AddMinutes(3)) < 0)
                {
                    Thread.Sleep(30000);
                    continue;
                }

                ProbesInterval new_interval = new ProbesInterval
                {
                    IntervalId = last_interval.IntervalId + 1,
                    Timestamp  = last_interval.Timestamp.AddMinutes(1),
                    Probes     = new List <Probe>(),
                    ActiveEsps = new List <ESP32_Device>()
                };


                List <Packet> toBeProcessed = await dbConnection.GetRawData(new_interval.Timestamp, new_interval.Timestamp.AddMinutes(1));

                //Per ogni pacchetto nell'intervallo ottengo un dizionario di <Hash pacchetto, Lista pacchetti con lo stesso hash> per avere tutte le rilevazioni
                Dictionary <string, List <Packet> > DetectionForHash = new Dictionary <string, List <Packet> >();
                foreach (Packet p in toBeProcessed)
                {
                    if (DetectionForHash.ContainsKey(p.Hash))
                    {
                        DetectionForHash[p.Hash].Add(p);
                    }
                    else
                    {
                        DetectionForHash.Add(p.Hash, new List <Packet> {
                            p
                        });
                    }
                }

                //elimino dati che non servono più
                toBeProcessed.Clear();
                toBeProcessed = null;

                //Elimino tutti i probe non detected da tutti gli ESP
                //var toberemoved = DetectionForHash.Where(pair => pair.Value.Count < 2).Select(pair => pair.Key).ToList();
                var toberemoved = DetectionForHash.Where(pair => pair.Value.Count != ESPManager.ESPs.Count).Select(pair => pair.Key).ToList();
                if (toberemoved.Count != 0)
                {
                    foreach (string hash in toberemoved)
                    {
                        DetectionForHash.Remove(hash);
                    }
                    toberemoved = null;
                }
                HashSet <string> esps = new HashSet <string>();
                foreach (var detection in DetectionForHash)
                {
                    Point point = default;
                    List <KeyValuePair <ESP32_Device, int> > detections = new List <KeyValuePair <ESP32_Device, int> >();
                    foreach (Packet p in detection.Value)
                    {
                        detections.Add(new KeyValuePair <ESP32_Device, int>(ESPManager.GetESPDevice(p.ESP_MAC), p.SignalStrength));
                    }

                    try
                    {
                        point = Interpolator2.Interpolate(detections);
                    }
                    catch
                    {
                        continue;
                    }

                    if (point != null)
                    {
                        if (point == default)
                        {
                            continue;
                        }
                        foreach (Packet p in detection.Value)
                        {
                            esps.Add(p.ESP_MAC);
                        }
                        new_interval.Probes.Add(new Probe()
                        {
                            SSID   = detection.Value[0].SSID,
                            Sender = new Device()
                            {
                                MAC        = detection.Value[0].MAC,
                                X_Position = point.X,
                                Y_Position = point.Y
                            },
                            Timestamp = detection.Value[0].Timestamp,
                            Hash      = detection.Key
                        });
                    }
                }
                new_interval.ActiveEsps.AddRange(esps.Select((mac) => ESPManager.GetESPDevice(mac)).ToList());

                //Invio i dati al database
                if (new_interval.ActiveEsps.Count != 0)
                {
                    try
                    {
                        bool result = await dbConnection.StoreProbesIntervalAsync(new_interval);

                        if (result is false)
                        {
                            dataCollectionTokenSource.Cancel();
                            ShowErrorMessage("Database connection error.\nData Collection has been stopped");
                            return;
                        }
                    }
                    catch
                    { //Se lo store del dato è fallito, segnalo e interrompo
                        dataCollectionTokenSource.Cancel();
                        ShowErrorMessage("Database connection error.\nData Collection has been stopped");
                        return;
                    }
                }
                last_interval = new_interval;
            }
        }