public async Task <List <EnergyPriceClass> > QueryEnergyPriceAsync()
        {
            Methods = new METHOD();
            string fileToday     = $"CurrentEnergyPrice{METHOD.DateTimeTZ():dd-MM-yyyy}";
            string fileYesterday = $"CurrentEnergyPrice{METHOD.DateTimeTZ().AddDays(-1):dd-MM-yyyy}";

            fileToday = Methods.GetFilePath(fileToday);
            //delete yesterday file, we dont need to collect them
            fileYesterday = Methods.GetFilePath(fileYesterday);
            if (File.Exists(fileYesterday))
            {
                File.Delete(fileYesterday);
            }

            if (File.Exists(fileToday)) //is there already file with today energy prices
            {
                var dataFromFile = await Methods.OpenExistingFile(fileToday);

                energyPriceToday = JsonSerializer.Deserialize <List <EnergyPriceClass> >(dataFromFile.ToString());
            }
            if (!File.Exists(fileToday)) //file with today energy price is missing
            {
                try
                {
                    string MarketPriceToday = METHOD.DateTimeTZ().ToString("dd.MM.yyyy");
                    energyPriceToday = await GetMarketPrice(MarketPriceToday);

                    var jsonString = JsonSerializer.Serialize(energyPriceToday);
                    await Methods.SaveStringToLocalFile(fileToday, jsonString);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Receive energy price from Cosmos exception: " + e.Message);
                }
            }
            return(energyPriceToday);
        }
Пример #2
0
        public async void CheckHeatingTime()
        {
            while (true)
            {
                if (TelemetryDataClass.SaunaStartedTime == DateTime.MinValue)
                {
                    var filename = Methods.GetFilePath(CONSTANT.FILENAME_SAUNA_TIME);
                    if (File.Exists(filename)) //this mean that sauna has been started and system has suddenly restarted/updated
                    {
                        var result = await Methods.OpenExistingFile(filename);

                        if (DateTime.TryParseExact(result, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out var SaunaStartedTime))
                        {
                            TelemetryDataClass.SaunaStartedTime = SaunaStartedTime;
                        }
                    }
                }
                if (TelemetryDataClass.SaunaStartedTime != DateTime.MinValue)
                {
                    int    TotalTimeSaunaHeatedInMinutes = (int)(METHOD.DateTimeTZ().DateTime - TelemetryDataClass.SaunaStartedTime).TotalMinutes;
                    string cmd = CommandNames.NO_COMMAND;
                    //turn saun on if it has heating time but not turned on
                    if (TotalTimeSaunaHeatedInMinutes < CONSTANT.MAX_SAUNA_HEATING_TIME && !TelemetryDataClass.isSaunaOn)
                    {
                        cmd = CommandNames.TURN_ON_SAUNA;
                    }
                    //turn sauna off if the time is over
                    if (TotalTimeSaunaHeatedInMinutes > CONSTANT.MAX_SAUNA_HEATING_TIME)
                    {
                        cmd = CommandNames.TURN_OFF_SAUNA;
                    }
                    _receiveData.ProcessCommand(cmd);
                }
                await Task.Delay(TimeSpan.FromMinutes(1)); //check every minute
            }
        }
        public async void ReadTemperature()
        {
            var _receiveData   = new ReceiveData();
            var _sensorsClient = new RinsenOneWireClient();
            var _sendListData  = new SendDataAzure();
            var Methods        = new METHOD();
            //currentSumOfTempDeltas is some bigger number than the delta (0,5) is used to determine temperature changes
            double SumOfTemperatureDeltas = 10;

            //initiate the list with the temps and names
            ListOfAllSensors = await _sensorsClient.ReadSensors();

            //fill out LastTemperatures and initial Temperature trend which is initially always TRUE
            ListOfAllSensors = UpdateSensorsTrendAndLastTemp(ListOfAllSensors, ListOfAllSensors);

            var filename = Methods.GetFilePath(CONSTANT.FILENAME_ROOM_TEMPERATURES);

            if (File.Exists(filename))
            {
                var dataFromFile = await Methods.OpenExistingFile(filename);

                List <SensorReading> SetRoomTemps = JsonSerializer.Deserialize <List <SensorReading> >(dataFromFile);
                SetTemperatures(SetRoomTemps);
            }
            while (true)
            {
                //get a new sensor readings and then update
                SensorReadings sensorReadings = await _sensorsClient.ReadSensors();

                ListOfAllSensors = UpdateSensorsTrendAndLastTemp(ListOfAllSensors, sensorReadings);

                //summing all the room temperature changes together add new deltas until it bigger that 4 degrees
                SumOfTemperatureDeltas += ListOfAllSensors.Temperatures.Where(x => x.isRoom).Sum(x => Math.Abs(x.Temperature - x.LastTemperature));

                //manage Livingroom heating actuator
                if (ListOfAllSensors.Temperatures.FirstOrDefault(x => x.RoomName == LIVING).isHeatingRequired)
                {
                    Pins.PinWrite(Pins.livingRoomHeatControlOut, PinValue.High);
                }
                else
                {
                    Pins.PinWrite(Pins.livingRoomHeatControlOut, PinValue.Low);
                }

                //manage Office heating actuator
                if (ListOfAllSensors.Temperatures.FirstOrDefault(x => x.RoomName == OFFICE).isHeatingRequired)
                {
                    Pins.PinWrite(Pins.homeOfficeHeatControlOut, PinValue.High);
                }
                else
                {
                    Pins.PinWrite(Pins.homeOfficeHeatControlOut, PinValue.Low);
                }

                //manage Piano heating actuator
                bool isPianoHeatingOn = ListOfAllSensors.Temperatures.FirstOrDefault(x => x.RoomName == PIANO).isHeatingRequired;
                await Shelly.SetShellySwitch(isPianoHeatingOn, Shelly.PianoHeating, nameof(Shelly.PianoHeating));

                //manage Bedroom heating actuator
                bool isBedroomHeatingOn = ListOfAllSensors.Temperatures.FirstOrDefault(x => x.RoomName == BEDROOM).isHeatingRequired;
                await Shelly.SetShellySwitch(isBedroomHeatingOn, Shelly.BedroomHeating, nameof(Shelly.BedroomHeating));

                //manage sauna temperature
                if (ListOfAllSensors.Temperatures.FirstOrDefault(x => x.RoomName == SAUNA).isHeatingRequired&& TelemetryDataClass.isSaunaOn)
                {
                    Pins.PinWrite(Pins.saunaHeatOutPin, PinValue.Low);
                }
                else
                {
                    Pins.PinWrite(Pins.saunaHeatOutPin, PinValue.High);
                }
                //if sauna extremely hot, then turn off
                if (ListOfAllSensors.Temperatures.FirstOrDefault(x => x.RoomName == SAUNA).Temperature > CONSTANT.EXTREME_SAUNA_TEMP)
                {
                    _receiveData.ProcessCommand(CommandNames.TURN_OFF_SAUNA);
                }

                //if all rooms has achieved their target temperature then turn system off
                if (ListOfAllSensors.Temperatures.Where(x => x.isRoom).All(x => !x.isHeatingRequired))
                {
                    _receiveData.ProcessCommand(CommandNames.REDUCE_TEMP_COMMAND);
                }

                //if all room temperatures together has changed more that 3 degrees then send it out to database
                if (Math.Abs(SumOfTemperatureDeltas) > 4)
                {
                    TelemetryDataClass.SourceInfo = $"Room temp changed {SumOfTemperatureDeltas:0.0}";
                    var monitorData = new
                    {
                        DeviceID    = "RoomTemperatures",
                        UtcOffset   = METHOD.DateTimeTZ().Offset.Hours,
                        DateAndTime = METHOD.DateTimeTZ().DateTime,
                        time        = METHOD.DateTimeTZ().ToString("HH:mm"),
                        TelemetryDataClass.SourceInfo,
                        ListOfAllSensors.Temperatures
                    };
                    await _sendListData.PipeMessage(monitorData, Program.IoTHubModuleClient, TelemetryDataClass.SourceInfo, "output");

                    SumOfTemperatureDeltas = 0;            //resetting to start summing up again
                }
                await Task.Delay(TimeSpan.FromMinutes(1)); //check temperatures every minute
            }
        }
        public async void QueryWiFiProbes()
        {
            http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}")));

            var filename = Methods.GetFilePath(CONSTANT.FILENAME_HOME_DEVICES);

            try
            {
                //open file and -> list of devices from Raspberry if the file exists
                if (File.Exists(filename))
                {
                    var result = await Methods.OpenExistingFile(filename);

                    WiFiDevice.WellKnownDevices = JsonSerializer.Deserialize <List <WiFiDevice> >(result).ToList();
                }
                else
                {
                    double unixTimestamp = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
                    //following will happen only if there is no file on Raspberry and the list will be loaded from the environment variables
                    WiFiDevice.WellKnownDevices.ForEach(x => x.StatusUnixTime = unixTimestamp);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"open file {e}");
            }

            await SendMacAddressToCosmos(WiFiDevice.WellKnownDevices);

            bool isAnyDeviceChanged = true;
            var  UnknownDevices     = new List <WiFiDevice>();

            while (true)
            {
                double unixTimestamp = METHOD.DateTimeToUnixTimestamp(DateTime.UtcNow);
                double timeOffset    = METHOD.DateTimeTZ().Offset.TotalHours;

                //if there are some items from PowerApps then proceed
                if (WiFiDevicesFromPowerApps.Any())
                {
                    //Add, Remove or Change WiFiDevices list according to WiFiDevices From PowerApps
                    WiFiDevice.WellKnownDevices = AddRemoveChangeDevices(WiFiDevicesFromPowerApps, WiFiDevice.WellKnownDevices);
                    WiFiDevicesFromPowerApps.Clear();
                    //send all devices to CosmosDB
                    await SendMacAddressToCosmos(WiFiDevice.WellKnownDevices);
                }
                //prepare multimac query
                //create a list of the MAC Addresses for multimac query
                List <string> deviceMacs = new List <string>();
                WiFiDevice.WellKnownDevices.ForEach(x => deviceMacs.Add(x.MacAddress));
                string            jsonMacAddresses     = JsonSerializer.Serialize(deviceMacs);
                string            urlMultiMac          = $"{urlKismet}/devices/multimac/devices.json";
                string            jsonContentFieldsMac = "json={\"fields\":" + jsonFields + ",\"devices\":" + jsonMacAddresses + "}";
                List <WiFiDevice> KismetKnownDevices   = await GetDevices(urlMultiMac, jsonContentFieldsMac);

                //clear devices list.
                WiFiDevicesToPowerApps.Clear();
                //building list of the local devices which are last seen
                foreach (var knownDevice in WiFiDevice.WellKnownDevices)
                {
                    foreach (var kismet in KismetKnownDevices)
                    {
                        if (knownDevice.MacAddress == kismet.MacAddress)
                        {
                            knownDevice.LastUnixTime = kismet.LastUnixTime;
                            knownDevice.LastSignal   = kismet.LastSignal;
                            knownDevice.SignalType   = kismet.SignalType;
                            knownDevice.SSID         = kismet.SSID;
                            knownDevice.WiFiName     = kismet.ProbedSSID;
                            if (kismet.SignalType.Contains("Wi-Fi"))
                            {
                                knownDevice.AccessPoint = WiFiDevice.WellKnownDevices.Where(x => x.MacAddress == kismet.LastBSSID).Select(x => x.DeviceName).DefaultIfEmpty("No AP").First();
                                if (string.IsNullOrEmpty(knownDevice.WiFiName) || knownDevice.WiFiName == "0")
                                {
                                    knownDevice.WiFiName = WiFiDevice.WellKnownDevices.Where(x => x.MacAddress == kismet.LastBSSID).Select(x => x.SSID).DefaultIfEmpty("No AP").First();
                                }
                            }
                            break;
                        }
                    }
                    //checking active devices and setting Active/NonActive statuses. Each device can have individual timewindow
                    knownDevice.IsChanged = false;                                                //this is just for debugging, no other reason
                    var durationUntilNotActive = (unixTimestamp - knownDevice.LastUnixTime) / 60; //timestamp in minutes
                    knownDevice.IsPresent = durationUntilNotActive < knownDevice.ActiveDuration;
                    if (knownDevice.IsPresent && !knownDevice.StatusChange)
                    {
                        knownDevice.StatusUnixTime = unixTimestamp;
                        knownDevice.StatusChange   = true;
                        isAnyDeviceChanged         = true;
                        knownDevice.IsChanged      = true;
                    }
                    if (!knownDevice.IsPresent && knownDevice.StatusChange)
                    {
                        knownDevice.StatusUnixTime = knownDevice.LastUnixTime;
                        knownDevice.StatusChange   = false;
                        isAnyDeviceChanged         = true;
                        knownDevice.IsChanged      = true;
                    }
                    //following list WiFiDevicesToPowerApps is used to send minimal data to PowerApps (sending only userdevices)
                    //this list will be sent as a response after PowerApps asks something or refreshing it's data
                    if (knownDevice.DeviceType != WiFiDevice.DEVICE)
                    {
                        WiFiDevicesToPowerApps.Add(new Localdevice()
                        {
                            DeviceOwner    = knownDevice.DeviceOwner,
                            DeviceName     = knownDevice.DeviceName,
                            DeviceType     = knownDevice.DeviceType,
                            IsPresent      = knownDevice.IsPresent,
                            StatusFrom     = METHOD.UnixTimeStampToDateTime(knownDevice.StatusUnixTime),
                            ActiveDuration = knownDevice.ActiveDuration,
                            MacAddress     = knownDevice.MacAddress,
                            SignalType     = knownDevice.SignalType,
                            IsChanged      = knownDevice.IsChanged
                        });
                    }
                    //build a list with the names who is expected to track
                    //this list will be sent through Azure Functions to the owners e-mail
                    if (knownDevice.DeviceType == WiFiDevice.MOBILE || knownDevice.DeviceType == WiFiDevice.WATCH || knownDevice.DeviceType == WiFiDevice.CAR)
                    {
                        //to be sure that every person is listed just once
                        if (!WiFiDevicesWhoIsChanged.Any(x => x.DeviceOwner == knownDevice.DeviceOwner) || !WiFiDevicesWhoIsChanged.Any())
                        {
                            WiFiDevicesWhoIsChanged.Add(new Localdevice()
                            {
                                DeviceOwner = knownDevice.DeviceOwner,
                                DeviceName  = knownDevice.DeviceName,
                                IsPresent   = knownDevice.IsPresent,
                                StatusFrom  = METHOD.UnixTimeStampToDateTime(knownDevice.StatusUnixTime),
                                SignalType  = knownDevice.SignalType,
                                IsChanged   = knownDevice.IsChanged
                            });
                        }
                    }
                }

                //update the list of the correct statuses, are they home or away
                foreach (var item in WiFiDevicesWhoIsChanged)
                {
                    item.IsChanged = false;
                    foreach (var device in WiFiDevicesToPowerApps)
                    {
                        if (item.DeviceOwner == device.DeviceOwner && (device.DeviceType == WiFiDevice.MOBILE || device.DeviceType == WiFiDevice.WATCH || device.DeviceType == WiFiDevice.CAR))
                        {
                            if (device.IsChanged)
                            {
                                item.IsChanged  = device.IsChanged;
                                item.DeviceName = device.DeviceName;
                                item.StatusFrom = device.StatusFrom.AddHours(timeOffset);
                                item.SignalType = device.SignalType;
                                item.IsPresent  = device.IsPresent;
                            }
                            //if device is exist and has'nt been changed, then mark it as unchanged and move to next item
                            //if device is not exist (not seen) but has been changed then mark it as unchanged and move to next item = do not notify leaving devices
                            //this is XOR
                            if (device.IsPresent ^ device.IsChanged)
                            {
                                item.IsChanged = false;
                                break;
                            }
                        }
                    }
                }

                //save the data locally into Raspberry
                var jsonString = JsonSerializer.Serialize(WiFiDevice.WellKnownDevices);
                await Methods.SaveStringToLocalFile(filename, jsonString);

                //send an e-mail only if someone has arrived at home or left the home
                if (WiFiDevicesWhoIsChanged.Any(x => x.IsChanged))
                {
                    string status = "Look who is at home:\n\n";

                    WiFiDevicesWhoIsChanged.ForEach(x => status += $"{(x.IsPresent ? x.DeviceOwner + " " + x.DeviceName + " at home from" : x.DeviceOwner + " not seen since")} {x.StatusFrom:HH:mm dd.MM.yyyy} \n ");
                    var    x          = WiFiDevicesWhoIsChanged.First(x => x.IsChanged);
                    string whoChanged = $"{(x.IsPresent ? x.DeviceOwner + " at home " : x.DeviceOwner + " not seen since")} {x.StatusFrom:HH:mm dd.MM.yyyy}";
                    _sendListData = new SendDataAzure();
                    TelemetryDataClass.SourceInfo = $"{whoChanged}";
                    //send data to CosmosDB
                    var monitorData = new
                    {
                        DeviceID = "HomeController",
                        TelemetryDataClass.SourceInfo,
                        status,
                        DateAndTime   = METHOD.DateTimeTZ().DateTime,
                        isHomeSecured = true
                    };
                    await _sendListData.PipeMessage(monitorData, Program.IoTHubModuleClient, TelemetryDataClass.SourceInfo, "output");
                }


                //if any mobile phone or watch is present then someone is at home
                IsAnyMobileAtHome = WiFiDevice.WellKnownDevices.Any(x => x.IsPresent && (x.DeviceType == WiFiDevice.MOBILE || x.DeviceType == WiFiDevice.WATCH || x.DeviceType == WiFiDevice.CAR));
                //if security mode automatic and home secured then unsecure home if any known mobile device is seen
                if (IsAnyMobileAtHome && TelemetryDataClass.isHomeSecured && !SomeoneAtHome.IsSecurityManuallyOn)
                {
                    SomeoneAtHome.SomeoneAtHomeChanged();
                }

                #region Known Device Listing, only for debugging

                //for local debugging only show the active/non active devices in console window
                if (isAnyDeviceChanged)
                {
                    isAnyDeviceChanged = false;
                    var sortedList = WiFiDevice.WellKnownDevices.OrderByDescending(y => y.IsPresent).ThenBy(w => w.AccessPoint).ThenBy(z => z.SignalType).ThenBy(x => x.DeviceName).ToList();
                    Console.WriteLine();
                    Console.WriteLine($"All known devices at: {METHOD.DateTimeTZ().DateTime:G}");
                    Console.WriteLine();
                    Console.WriteLine($"   |   From   | Status  |          Device           |        WiFi network      |        AccessPoint       |  SignalType");
                    Console.WriteLine($"   |  ------  | ------- |         --------          |           -----          |           -----          |  --------  ");
                    foreach (var device in sortedList)
                    {
                        if (device.LastUnixTime > 0 && device.SignalType != "Wi-Fi AP" && device.DeviceOwner != "Unknown" && device.DeviceType != WiFiDevice.DEVICE) //show only my own ever seen LocalUserDevices devices
                        {
                            Console.WriteLine($" {(device.IsChanged ? "1" : " ")} " +
                                              $"| {METHOD.UnixTimeStampToDateTime(device.StatusUnixTime).AddHours(timeOffset):T} " +
                                              $"| {(device.IsPresent ? "Active " : "Not Act")} " +
                                              $"| {device.DeviceName}{"".PadRight(26 - (device.DeviceName.Length > 26 ? 26 : device.DeviceName.Length))}" +
                                              $"| {device.WiFiName}{"".PadRight(26 - (!string.IsNullOrEmpty(device.WiFiName) ? (device.WiFiName.Length > 26 ? 26 : device.WiFiName.Length) : 0))}" +
                                              $"| {device.AccessPoint}{"".PadRight(26 - (!string.IsNullOrEmpty(device.AccessPoint) ? (device.AccessPoint.Length > 26 ? 26 : device.AccessPoint.Length) : 0))}" +
                                              $"| {device.SignalType} ");
                        }
                    }
                    Console.WriteLine();
                }

                #endregion

                #region Unknown Devices Debugging

                //prepare last active devices query
                string            urlLastActive       = $"{urlKismet}/devices/last-time/{CONSTANT.ACTIVE_DEVICES_IN_LAST}/devices.json";
                string            jsonContentFields   = "json={\"fields\":" + jsonFields + "}";
                List <WiFiDevice> KismetActiveDevices = await GetDevices(urlLastActive, jsonContentFields);

                //removing all known devices from the last seen devices list
                //known devices are all locally registered devices in the list WiFiDevice.WifiDevices
                var tempDelList      = new List <WiFiDevice>();
                var AllActiveDevices = new List <WiFiDevice>(KismetActiveDevices);
                foreach (var kismet in KismetActiveDevices)
                {
                    foreach (var knownDevice in WiFiDevice.WellKnownDevices)
                    {
                        if (kismet.MacAddress == knownDevice.MacAddress || kismet.LastSignal < CONSTANT.SIGNAL_TRESHOLD || (kismet.CommonName == kismet.MacAddress && kismet.Manufacture == "Unknown"))
                        {
                            tempDelList.Add(kismet);
                            break;
                        }
                    }
                }
                KismetActiveDevices.RemoveAll(i => tempDelList.Contains(i));

                //adding new members to the close devices list
                if (KismetActiveDevices.Any())
                {
                    var  tempAddList = new List <WiFiDevice>();
                    bool isNewItem   = true;
                    foreach (var kismet in KismetActiveDevices)
                    {
                        foreach (var unknownDevice in UnknownDevices)
                        {
                            if (kismet.MacAddress == unknownDevice.MacAddress)
                            {
                                unknownDevice.Count++;
                                unknownDevice.LastUnixTime = kismet.LastUnixTime;
                                unknownDevice.WiFiName     = kismet.ProbedSSID;
                                if (kismet.SignalType.Contains("Wi-Fi"))
                                {
                                    //get device AccessPoint and WIFI network names from Kismet (if reported by device)
                                    List <WiFiDevice> KismetOneMac = new List <WiFiDevice>();
                                    string            urlOneMac    = $"{urlKismet}/devices/by-mac/{kismet.MacAddress}/devices.json";
                                    KismetOneMac = await GetDevices(urlOneMac, jsonContentFields);

                                    //have to check KismetOneMac list because sometimes it is empty
                                    if (KismetOneMac.Any())
                                    {
                                        unknownDevice.AccessPoint = AllActiveDevices.Where(x => x.MacAddress == KismetOneMac.First().LastBSSID).Select(x => x.BaseName).DefaultIfEmpty("No AP").First();
                                        if (string.IsNullOrEmpty(kismet.ProbedSSID) || unknownDevice.WiFiName == "0")
                                        {
                                            unknownDevice.WiFiName = AllActiveDevices.Where(x => x.MacAddress == KismetOneMac.First().LastBSSID).Select(x => x.SSID).DefaultIfEmpty("No AP").First();
                                        }
                                    }
                                }
                                isNewItem = false;
                                break;
                            }
                            else
                            {
                                isNewItem = true;
                            }
                        }
                        if (isNewItem)
                        {
                            tempAddList.Add(kismet);
                        }
                    }
                    UnknownDevices.AddRange(tempAddList.ToArray());

                    UnknownDevices.RemoveAll(x => (unixTimestamp - x.LastUnixTime) / 60 > 120); //remove all entries older that 2 hour

                    //local debugging: show the devices list in console only if some device has been added
                    if (tempAddList.Any() && UnknownDevices.Any())
                    {
                        var sortedList = UnknownDevices.OrderBy(x => x.SignalType).ThenByDescending(y => y.LastUnixTime).ToList();
                        Console.WriteLine();
                        Console.WriteLine($"All unknown devices at: {METHOD.DateTimeTZ().DateTime:G}");
                        Console.WriteLine();
                        Console.WriteLine($"dB  | First | Last  |    Mac Address    |Count |  SignalType   |         WiFi network      |         AccessPoint       |    Common Name     | Manufacturer ");
                        Console.WriteLine($" -  | ----  | ----  |    -----------    | ---  |  ----------   |          ---------        |          ---------        |    -----------     |  -----------  ");

                        foreach (var device in sortedList)
                        {
                            Console.WriteLine($"{device.LastSignal}{"".PadRight(device.LastSignal < 0 ? 1 : 3)}" +
                                              $"| {METHOD.UnixTimeStampToDateTime(device.FirstUnixTime).AddHours(timeOffset):t} " +
                                              $"| {METHOD.UnixTimeStampToDateTime(device.LastUnixTime).AddHours(timeOffset):t} " +
                                              $"| {device.MacAddress} " +
                                              $"| {device.Count}{"".PadRight(device.Count < 10 ? 3 : device.Count < 100 ? 2 : 1)} " +
                                              $"| {device.SignalType}{"".PadRight(14 - (!string.IsNullOrEmpty(device.SignalType) ? (device.SignalType.Length > 14 ? 14 : device.SignalType.Length) : 0))}" +
                                              $"| {device.WiFiName}{"".PadRight(26 - (!string.IsNullOrEmpty(device.WiFiName) ? (device.WiFiName.Length > 26 ? 26 : device.WiFiName.Length) : 0))}" +
                                              $"| {device.AccessPoint}{"".PadRight(26 - (!string.IsNullOrEmpty(device.AccessPoint) ? (device.AccessPoint.Length > 26 ? 26 : device.AccessPoint.Length) : 0))}" +
                                              $"| {device.CommonName}{"".PadRight(19 - (!string.IsNullOrEmpty(device.CommonName) ? (device.CommonName.Length > 19 ? 19 : device.CommonName.Length) : 0))}" +
                                              $"| {device.Manufacture}");
                        }
                        Console.WriteLine();
                    }
                }
                #endregion

                await Task.Delay(TimeSpan.FromSeconds(60)); //check statuses every 10 millisecond
            }
        }