예제 #1
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;
            }
        }
예제 #2
0
        public void Main()
        {
            visualizer = new DataVisualizer();
            log        = new Logger();

            //Showing Splash Screen
            splash = new SplashScreen();
            splash.Show();

            //Loading configuration
            splash.ShowConfLoadingSplashScreen();
            configuration = Configuration.LoadConfiguration();
            if (configuration is null)
            {
                ShowErrorMessage("Unable to load the configuration...\nExiting.");
                Environment.Exit(0);
                return;
            }
            ESPManager.Initialize(configuration.Devices);

            //Testing Database connection
            splash.ShowDBConneLoadingSplashScreen();
            DatabaseConnection dbConnection = new DatabaseConnection();

            if (dbConnection.TestConnection() == false) //not connected after 3 tries
            {
                ShowErrorMessage("Unable to connect to Database...\nExiting.");
                Environment.Exit(0);
                return;
            }

            //Connecting to Devices
            splash.ShowDeviceAwaitingSplashScreen();
            broadcasterTokenS = new CancellationTokenSource();
            UdpBroadcaster.Start(broadcasterTokenS.Token);
            dataCollector = new DataCollector();
            dataCollector.Initialize();
            if (dataCollector.Initialized is false)
            {
                ShowErrorMessage("Unable to initialize devices...\nExiting.");
                Environment.Exit(0);
                return;
            }

            //Setting up the notification icon
            notifyIcon = new System.Windows.Forms.NotifyIcon();
            Stream iconStream = Assembly.GetAssembly(typeof(Core.Controls.MessageBox)).GetManifestResourceStream("Core.Resources.icon.ico");

            notifyIcon.Icon    = new System.Drawing.Icon(iconStream);
            notifyIcon.Visible = true;
            notifyIcon.Click  += NotifyIcon_Click;
            toast = new ToastMenu();
            toast.MouseDoubleClick += Toast_MouseDoubleClick;
            toast.Deactivated      += MenuFlyout_Deactivated;
            toast.ExitCLicked      += Exit;
            toast.ShowGraphClicked += Toast_ShowGraphClicked;
            toast.ShowLogClicked   += Toast_ShowLogClicked;

            //starting data collection

            ShowMessage("Starting data collection");
            dataCollector.StartDataCollection();

            //Opening visualizer
            splash.Close();
        }
예제 #3
0
        private async Task DataCollectionLoop(CancellationToken token)
        {
            if (server.IsStarted is false)
            {
                return;
            }
            while (token.IsCancellationRequested is false)
            {
                dbConnection.TestConnection();
                if (dbConnection.Connected is false)
                { //Se la connessione è caduta, segnalo e riprovo dopo 10 secondi
                    if (dbConnection.Connected is false)
                    {
                        ShowErrorMessage("Database connection has gone down.\nPackets will be stored locally waiting for a new connection.");
                    }
                    Thread.Sleep(10000);
                    continue;
                }

                if (storeFails.Count == 0)
                { // get new messages only if there are no pendents packets
                    server.NewMessageEvent.WaitOne(2000);
                    while (server.EnquedMessages > 0)
                    { //ottengo tutti i nuovi messaggi dalla coda del server tcp
                        Data_Message message = server.GetNextMessage() as Data_Message;
                        if (message is null)
                        {
                            continue;
                        }
                        DeviceData data = DeviceData.FromJson(message.Payload);
                        if (data is null)
                        {
                            Logger.Log("An ESP sent a wrong DEVICE_DATA message" + "\r\n");
                            continue;
                        }
                        var esp = ESPManager.GetESPDevice(data.Esp_Mac);
                        Logger.Log("An ESP sent DEVICE_DATA\t\tx: " + esp?.X_Position + " y: " + esp?.Y_Position + "\r\n");
                        foreach (Packet p in data.Packets)
                        {
                            p.ESP_MAC   = data.Esp_Mac;
                            p.Timestamp = p.Timestamp.AddHours(2);
                            p.Hash      = Utilities.Hash.SHA1(p.MAC + p.SSID + p.Seq_Num + p.Timestamp.ToString("yyyy/MM/dd'T'HH:mm:ss.fff"));
                            toBeStored.Enqueue(p);
                        }
                    }
                }
                else    //se ci sono dati non inviati al database, li reinserisco in coda
                {
                    while (storeFails.Count > 0)
                    {
                        toBeStored.Enqueue(storeFails.Dequeue());
                    }
                }

                //Invio i dati al database
                while (toBeStored.Count > 0)
                {
                    Packet p = toBeStored.Dequeue();
                    try
                    {
                        bool result = await dbConnection.StorePacketAsync(p);

                        if (result is false)
                        {
                            storeFails.Enqueue(p);
                            break;
                        }
                    }
                    catch
                    { //Se lo store del dato è fallito, segnalo e interrompo
                        storeFails.Enqueue(p);
                        break;
                    }
                }

                //Se ci sono dati non inviati al database, li inserisco nella lista di fail
                while (toBeStored.Count > 0)
                {
                    storeFails.Enqueue(toBeStored.Dequeue());
                }
            }
        }