Пример #1
0
        /// <summary>
        /// It looks for the compatible devices (discovery + analysis). Then, it asks
        /// for the user to choose the device. The selected device is returned
        /// through a CompatibleEndPoint object. It contains the id, service and
        /// characteristic name.
        /// </summary>
        /// <returns>The complete device id (or CompatibleEndPoint with all fields set as null if none were selected)</returns>
        static async Task <CompatibleEndPoint> AutomaticScan()
        {
            BleUtility.Discovery bleDiscovery = new BleUtility.Discovery();
            bleDiscovery.Start();

            LogHelper.Overwrite(true);
            LogHelper.NewLine(false);

            while (!bleDiscovery.HasEnded())
            {
                Thread.Sleep(50);
            }
            LogHelper.Overwrite(false);
            LogHelper.NewLine(true);
            LogHelper.Log("");

            LogHelper.Ok("Devices:");
            LogHelper.IncrementIndentLevel();
            List <DeviceInformation> devices = bleDiscovery.GetDevices();

            foreach (DeviceInformation device in devices)
            {
                LogHelper.Ok(device.Id + " " + device.Name);
            }
            LogHelper.DecrementIndentLevel();

            List <CompatibleEndPoint> compatibleEndPoints = new List <CompatibleEndPoint>();

            LogHelper.Pending("Checking compatibility of each device");
            LogHelper.IncrementIndentLevel();
            foreach (DeviceInformation device in devices)
            {
                LogHelper.Pending("Checking compatibility of device " + device.Id.Split("-").Last());
                LogHelper.IncrementIndentLevel();

                LogHelper.Pending("Connecting to device...");
                BluetoothLEDevice connection = await BleUtility.Connect(device.Id);

                if (connection == null)
                {
                    LogHelper.DecrementIndentLevel();
                    LogHelper.Warn("Failed to connect (doesn't mean that it's incompatible)");
                    continue;
                }
                LogHelper.Ok("Connected");

                LogHelper.Pending("Looking for services...");
                IReadOnlyList <GattDeviceService> services = await BleUtility.GetServices(connection);

                if (services == null)
                {
                    LogHelper.DecrementIndentLevel();
                    LogHelper.Warn("Gatt communication failed");
                    continue;
                }
                else if (services.Count == 0)
                {
                    LogHelper.DecrementIndentLevel();
                    LogHelper.Warn("No services found");
                    continue;
                }
                LogHelper.Ok(services.Count + " service(s) found");

                LogHelper.Pending("Looking for characteristics for each service...");
                LogHelper.IncrementIndentLevel();
                foreach (GattDeviceService service in services)
                {
                    LogHelper.Pending("Looking for characteristics of service " + DisplayHelpers.GetServiceName(service));
                    LogHelper.IncrementIndentLevel();

                    IReadOnlyList <GattCharacteristic> characteristics = await BleUtility.GetCharacteristics(service);

                    if (characteristics == null)
                    {
                        LogHelper.DecrementIndentLevel();
                        LogHelper.Warn("Failed to retrieve characteristics");
                        service.Dispose();
                        continue;
                    }
                    else if (characteristics.Count == 0)
                    {
                        LogHelper.DecrementIndentLevel();
                        LogHelper.Warn("No characteristics found");
                        service.Dispose();
                        continue;
                    }
                    LogHelper.Ok(characteristics.Count + " characteristic(s) found");

                    LogHelper.Pending("Checking compatibility of each characteristic...");
                    LogHelper.IncrementIndentLevel();
                    int compatibleCpt = 0;
                    foreach (GattCharacteristic characteristic in characteristics)
                    {
                        LogHelper.Pending("Checking characteristic " + DisplayHelpers.GetCharacteristicName(characteristic) + "...");

                        if (BleUtility.IsWriteableCharateristic(characteristic))
                        {
                            CompatibleEndPoint endPoint = new CompatibleEndPoint(
                                device.Id,
                                device.Name,
                                DisplayHelpers.GetServiceName(service),
                                DisplayHelpers.GetCharacteristicName(characteristic)
                                );

                            compatibleCpt++;
                            compatibleEndPoints.Add(endPoint);
                            LogHelper.Ok("Compatible!");
                        }
                        else
                        {
                            LogHelper.Warn("Not compatible");
                        }
                    }

                    service.Dispose();
                    LogHelper.DecrementIndentLevel();
                    LogHelper.Ok(compatibleCpt + " compatible endpoint(s) found");
                    LogHelper.DecrementIndentLevel();
                }
                LogHelper.Ok("Finished looking for characteristics");
                LogHelper.DecrementIndentLevel();

                LogHelper.Ok("Finished compatibility check of device " + device.Id.Split('-').Last());
                LogHelper.DecrementIndentLevel();
            }
            LogHelper.DecrementIndentLevel();
            LogHelper.Ok("Finished analyzing devices");

            if (compatibleEndPoints.Count == 0)
            {
                LogHelper.Error("No compatible device found");
                LogHelper.Error("Make sure that you're not already connected to it");
                return(new CompatibleEndPoint(null, null, null, null));
            }
            else
            {
                LogHelper.Ok("Compatible device(s):");
                LogHelper.IncrementIndentLevel();
                string[] ids = new string[compatibleEndPoints.Count];
                for (int i = 0; i < compatibleEndPoints.Count; i++)
                {
                    CompatibleEndPoint compatibleEndPoint = compatibleEndPoints.ElementAt(i);
                    LogHelper.Ok("name = '" + compatibleEndPoint.deviceName + "' id = '" + compatibleEndPoint.deviceId + "'");
                    ids[i] = compatibleEndPoint.deviceId + (compatibleEndPoint.deviceName != "" ? (" " + compatibleEndPoint.deviceName) : "");
                }
                LogHelper.DecrementIndentLevel();

                int choice = LogHelper.AskUserToChoose("Choose the device to use: ", ids);
                bleDiscovery.Dispose();
                return(compatibleEndPoints.ElementAt(choice));
            }
        }
Пример #2
0
        /// <summary>
        /// The program Loop: CTRL+C to stop it properly
        /// </summary>
        /// <param name="characteristic"></param>
        static void Loop(GattCharacteristic characteristic)
        {
            SoundListener soundListener = new SoundListener();

            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) {
                e.Cancel    = true;
                keepRunning = false;
            };
            LogHelper.Ok("Program running. Press CTRL+C to stop");

            #region variables (prevents reallocation)

            // Rectangle in the middle of the screen
            Rectangle rect      = new Rectangle(1920 / 4, 1080 / 4, 1920 / 4 * 2, 1080 / 4 * 2);
            String    colorCode = "";
            Color     color;
            int       soundLevel;
            String    brightness;
            String    textToWrite;

            #endregion

            #region configuration

            bool   sensitiveToBass  = Configuration.audioSensibility == Configuration.AudioSensibility.BASS_LEVEL;
            bool   dynamicSmoothing = Configuration.smoothingMode == Configuration.SmoothingMode.DYNAMIC;
            bool   valueSmoothing   = Configuration.smoothingMode == Configuration.SmoothingMode.VALUE;
            double smoothness       = Configuration.smoothingValue;

            #endregion

            int current = -1; // Smooth brightness variation
            int cpt     = 0;  // Used to know when to read the screen's pixels
            soundListener.ListenForBass(sensitiveToBass);

            while (keepRunning)
            {
                if (Configuration.audioSensibility != Configuration.AudioSensibility.NONE)
                {
                    soundLevel = (int)((sensitiveToBass ? soundListener.GetBassLevel() : soundListener.GetSoundLevel()) * 100f); // Between 0.0f and 100.0f

                    if (current == -1)
                    {
                        current = soundLevel;
                    }

                    if (dynamicSmoothing)
                    {
                        current = (current + soundLevel) / 2;
                    }
                    else if (current < soundLevel && valueSmoothing && smoothness > 0)
                    {
                        current = Math.Min((int)(current + 100 / smoothness), soundLevel);
                    }
                    else if (smoothness > 0)
                    {
                        current = Math.Max((int)(current - 100 / smoothness), soundLevel);
                    }
                    else
                    {
                        current = soundLevel;
                    }

                    // Format: 7e 00 01 brightness 00 00 00 00 ef
                    // brightness: 0x00-0x64 (0-100)
                    // So we need to convert the soundLevel to hex so that 100.0f is 0x64 and 0.0f is 0x00
                    brightness  = (current).ToString("X");
                    textToWrite = "7e0001" + brightness + "00000000ef";
                    _           = BleUtility.WriteHex(textToWrite, characteristic); // we don't want it to be blocking
                }

                if (Configuration.colorSensibility != Configuration.ColorSensibility.NONE)
                {
                    // We don't want to analyze pixels as fast as we check for the sound level
                    cpt++;
                    if (cpt == 10)
                    {
                        new Thread(() =>
                        {
                            color = ScreenUtils.CalculateAverageScreenColorAt(rect);

                            if (color.GetBrightness() >= 0.85f)
                            {
                                // white
                                colorCode = "86";
                            }
                            else if (color.GetHue() < 25 || color.GetHue() >= 330)
                            {
                                // red
                                colorCode = "80";
                            }
                            else if (color.GetHue() >= 25 && color.GetHue() < 65)
                            {
                                // yellow
                                colorCode = "84";
                            }
                            else if (color.GetHue() >= 65 && color.GetHue() < 180)
                            {
                                // green
                                colorCode = "82";
                            }
                            else if (color.GetHue() >= 180 && color.GetHue() < 200)
                            {
                                // cyan
                                colorCode = "83";
                            }
                            else if (color.GetHue() >= 200 && color.GetHue() < 250)
                            {
                                // blue
                                colorCode = "81";
                            }
                            else if (color.GetHue() >= 250 && color.GetHue() < 330)
                            {
                                // magenta
                                colorCode = "85";
                            }

                            _ = BleUtility.WriteHex("7e0003" + colorCode + "03000000ef", characteristic);
                        }).Start();

                        cpt = 0;
                    }
                }

                Thread.Sleep(50);
            }

            soundListener.Dispose();
        }
Пример #3
0
        /// <summary>
        /// The actual program, needs to be waited
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        static async Task Run(string[] args)
        {
            LogHelper.PrintHeader();

            LogHelper.PrintTitle("Configuration");
            bool configSucceed = await Configure(args);

            if (!configSucceed)
            {
                LogHelper.Error("Something went wrong during configuration");
            }
            else
            {
                #region connection

                LogHelper.PrintTitle("Connection");
                LogHelper.Pending("Looking for BLE device of id " + Configuration.device.deviceId);
                device = await BleUtility.Connect(Configuration.device.deviceId);

                if (device == null)
                {
                    LogHelper.Error("Failed to connect to device");
                }

                #endregion

                #region services

                GattDeviceService targettedService = null;
                if (device != null)
                {
                    LogHelper.PrintTitle("Services");
                    LogHelper.Pending("Looking for service " + Configuration.device.deviceServiceName + "...");

                    IReadOnlyList <GattDeviceService> services = await BleUtility.GetServices(device);

                    if (services != null)
                    {
                        LogHelper.Ok(String.Format("Found {0} service(s)", services.Count));
                        foreach (var service in services)
                        {
                            if (DisplayHelpers.GetServiceName(service) == Configuration.device.deviceServiceName)
                            {
                                LogHelper.Ok("Found service " + Configuration.device.deviceServiceName);
                                targettedService = service;
                                break;
                            }
                        }

                        if (targettedService == null)
                        {
                            LogHelper.Error("Couldn't find service " + Configuration.device.deviceServiceName);
                        }
                    }
                    else
                    {
                        LogHelper.Error("Device unreachable");
                    }
                }

                #endregion

                #region caracteristics

                GattCharacteristic characteristic = null;
                if (targettedService != null)
                {
                    LogHelper.PrintTitle("Caracteristics");
                    LogHelper.Pending("Looking for characteristic " + Configuration.device.deviceCharacteristicName + "...");
                    IReadOnlyList <GattCharacteristic> characteristics = await BleUtility.GetCharacteristics(targettedService);

                    if (characteristics == null)
                    {
                        LogHelper.Error("Could not find characteristics of " + Configuration.device.deviceName);
                    }
                    else
                    {
                        foreach (var charact in characteristics)
                        {
                            if (DisplayHelpers.GetCharacteristicName(charact) == Configuration.device.deviceCharacteristicName)
                            {
                                LogHelper.Ok("Found characteristic");
                                characteristic = charact;
                            }
                        }

                        if (characteristic == null)
                        {
                            LogHelper.Error("Could not find characteristic " + Configuration.device.deviceCharacteristicName);
                        }
                    }
                }

                #endregion

                #region show config

                LogHelper.PrintTitle("Save your config");
                LogHelper.Ok("Using configuration:");
                LogHelper.Log(Configuration.GetArgumentDetails());
                LogHelper.Log("\"" + Configuration.ToArgument() + "\"");
                LogHelper.Ok("Copy the line below, and run the program with this argument to [...]");
                LogHelper.Ok("[...] start the program automatically with the current configuration");

                #endregion

                #region communication

                if (characteristic != null)
                {
                    LogHelper.PrintTitle("Communication");

                    if (BleUtility.IsWriteableCharateristic(characteristic))
                    {
                        Loop(characteristic);
                    }
                    else
                    {
                        LogHelper.Error("This characteristic does not have either the 'Write' or 'WriteWithoutResponse' properties");
                    }
                }

                #endregion
            }

            #region cleanup

            LogHelper.PrintTitle("Cleanup");
            LogHelper.Pending("Exiting properly");
            device?.Dispose();
            LogHelper.Ok("Done. Type a key to exit");
            Console.ReadKey(true);

            #endregion
        }