Welcome to the new FlexRadio Community! Please review the new Community Rules and other important new Community information on the Message Board.
If you are having a problem, please refer to the product documentation or check the Help Center for known solutions.
Need technical support from FlexRadio? It's as simple as Creating a HelpDesk ticket.

GUIClient

Jim Shaffer
Jim Shaffer Member ✭✭
edited January 2020 in SmartSDR API
I probably should have asked this long ago, but what is the GUIClient structure all about?  I presume it relates to the multi-user feature introduced in V3, but I've been able to muddle along without considering it, and maybe I need to do so, even though my client doesn't support multiple users.


I do get a GUIClientAdded event using FlexLib 2.5.1.

Answers

  • Mark_W3II
    Mark_W3II Member ✭✭✭
    edited January 2020

    My response is for persons using the V3 FlexAPI with a V2.5 or V3.+ radio.


    For V3 radios the GUIClient represents the 1 or 2 connected clients to the radio. When you implement a non-GUI client to control the radio it should be in context to 1 of the the two possible clients. I have noticed the radio status sent to the non-GUI clients changes depending if you are bound to a client or not. In short it depends on what your are doing with the Flex API if binding to client matters. To err on the side of caution I would bind to a client. In most use cases there is only one client so binding takes no user input. When you discover there are two connected GUI clients sharing the radio you should bind to the client you want to share control with. Hopefully this was more helpful than confusing. For V2 this property can be ignored. Note the radio object contains its version from discovery which is before you connect to it.

    73 
  • Jim Shaffer
    Jim Shaffer Member ✭✭
    edited January 2020
    Thanks Mark.  I'm using FlexLib 2.5.1 and setting API.IsGUI = true.  I always see a GUIClient added after I connect, and then it gets removed later.  At this point, I'm not sure what the GUIClient signifies if anything.  Is it just for nonGUI clients?
  • Mark_W3II
    Mark_W3II Member ✭✭✭
    edited January 2020
    If you are connecting as the GUI client then you are all set. BTW are you a GUI client or a utility? The reason I ask is on a V2 radio there can be only 1 GUI client therefore your app can't run if SmartSDR / Maestro is connected. Or on V3 if there are already 2 clients connected.
  • James Whiteway
    edited January 2020
    In the context that FRS uses, a GUI client, is an application that displays a panadapter and or, a waterfall. If your application does not need to display either, or both of those, then you can safely set isGUI= false. As Mark explained above, if you are using v3.x or later then the radio will accept two GUI clients. James WD5GWY
  • Jim Shaffer
    Jim Shaffer Member ✭✭
    edited January 2020
    Well I'm definitely a GUI client, because I display a pan adapter, and my app sets API.IsGUI = true.
    I notice that there is a GUIClient object created after I connect.  I then load a profile, and the client object gets removed.
    My original question remains, "What is a GUIClient object, and how do I use it?"
  • James Whiteway
    edited January 2020
    If you are already familiar with this, I apologize for assuming otherwise.
    An object in an object oriented programming sense, is explained here:

    https://en.m.wikipedia.org/wiki/Objec...

    So, if your application has a graphical users interface, then " technically" it is a GUI Client. But, FRS differentiates that a bit further in their use of it( isGUI= true/false) to let the radio know which clients it can send data such as panadapters and waterfalls.
    If your application uses that data, set isGUI to false. You'll see in your Debugger no output to your application for that data.
    My initial programming attempt for my 6000 radios, was simply a control surface. No need to set isGUI to true. And it would( and still does) run fine right alongside SSDR or even the m series front end.
    Prior to version 3, there could only be one GUI client receiving panadapter and waterfall info. Either the m radio's internal SSDR version or non m model using SSDR on the pc.
    With v3 and up, that changed now, there can be two gui clients receiving panadapter and waterfall data.
    You just have to do more detailed work to get the correct data for your application.
    James
    WD5GWY As for the profile issue. You'll have to create that in your application. Otherwise, the radio will send a set of default settings to your program.
  • Jim Shaffer
    Jim Shaffer Member ✭✭
    edited January 2020
    So if I understand correctly, a Version 3 radio can support two GUI clients, and an application binds to the client it is supporting.
    I'd be interested to see how this is done though,  That's what I've been trying to get a handle on.
  • James Whiteway
    edited January 2020
    I'm away from my computer right now.( over the road trucker) But, will be back by Saturday. When you first connect to your radio, one of the responses back from the radio s the ClientID for your application. It is assigned each time you connect to the radio and is different each time you reconnect. When you subscribe to events like the panadapter and waterfall, you can compare the ClientID to the ID's for the panadapter and/or waterfall. And if they are the same you can process the data for your application. If you don't, you'll get some really strange things happening. ( double panadapter traces for one) In Visual Studio 2019 Community edition, you can set watches for different things and watch the incoming data. What language are you programming with? The FlexLib API is written in C#. I find it easier to use the same language rather than using a different language. ( I started out using Visual Basic. But, I found it a hassle getting the syntax correct to work with dll's written in C#) James WD5GWY
  • Jim Shaffer
    Jim Shaffer Member ✭✭
    edited January 2020
    This is a long post.
    As I've mentioned, I don't really understand how to use  the GUIClient structure.  
    I've written the following little test program which uses FlexLib V3.1.7.  It just connects to the first radio on my LAN, waits 5 seconds, then disconnects.  I notice that I do get a GUIClient object created, along with a panadapter and a slice, but the GUIClient is then removed.  I'm not sure what that's all about.

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using Flex.Smoothlake.FlexLib;

    namespace testFlexV3_2
    {
        class Program
        {
            private static Radio theRadio { get { return (API.RadioList.Count == 0) ? null : API.RadioList[0]; } }

            static void Main(string[] args)
            {
                API.IsGUI = true;
                API.ProgramName = "testFlexV3_2";
                API.RadioAdded += radioAddedHandler;
                API.Init();

                // await a radio.
                while (theRadio == null) { Thread.Sleep(100); }
                Debug.WriteLine("dbg:radio found:" + theRadio.Serial);

                connect();

                // just wait 5 seconds.
                Thread.Sleep(5000);

                // done
                Debug.WriteLine("dbg:testing done");
                if (theRadio != null)
                {
                    if (theRadio.Connected) theRadio.Disconnect();
                }
                API.CloseSession();

                Console.Write("Press Enter to end:");
                string dmy = Console.ReadLine();
                Environment.Exit(0);
            }

            private static void radioAddedHandler(Radio r)
            {
                Debug.WriteLine("dbg:radioAddedHandler:" + r.Serial);
                API.RadioList.Add(r);
            }

            private static bool connect()
            {
                Debug.WriteLine("dbg:connect:");
                theRadio.GUIClientAdded += guiClientAddedHandler;
                theRadio.GUIClientRemoved += guiClientRemovedHandler;
                theRadio.PanadapterAdded += panAdapterAddedHandler;
                theRadio.PanadapterRemoved += panAdapterRemovedHandler;
                theRadio.SliceAdded += sliceAddedHandler;
                theRadio.SliceRemoved += sliceRemovedHandler;

                bool rv = theRadio.Connect();
                if (rv)
                {
                    Debug.WriteLine("dbg:connect:connected to" + theRadio.Serial);
                }
                else
                {
                    Debug.WriteLine("dbg:connect:not connected");
                }
                return rv;
            }

            internal static GUIClient myClient = null;
            private static void guiClientAddedHandler(GUIClient client)
            {
                Debug.WriteLine("dbg:guiClientAdded:" +
                    client.ClientID + ' ' +
                    client.IsThisClient.ToString() + ' ' +
                    client.ClientHandle + ' ' +
                    client.Program + ' ' +
                    client.Station + ' ' +
                    client.IsLocalPtt.ToString() + ' ' +
                    client.IsAvailable.ToString());

                if (myClient == null) myClient = client;
            }

            private static void guiClientRemovedHandler(GUIClient client)
            {
                Debug.WriteLine("dbg:guiClientRemovedHandler:" + client.ClientID);
                if ((myClient != null) && (myClient.ClientID == client.ClientID)) myClient = null;
            }

            internal static List<Panadapter> panAdapters = new List<Panadapter>();
            private static void panAdapterAddedHandler(Panadapter pan, Waterfall w)
            {
                Debug.WriteLine("dbg:panAdapterAddedHandler:" + pan.ToString());
                panAdapters.Add(pan);
            }

            private static void panAdapterRemovedHandler(Panadapter pan)
            {
                Debug.WriteLine("dbg:panAdapterRemovedHandler:" + pan.ToString());
                panAdapters.Remove(pan);
            }

            internal static List<Slice> slices = new List<Slice>();
            private static void sliceAddedHandler(Slice s)
            {
                Debug.WriteLine("dbg:sliceAddedHandler:" + s.ToString());
                slices.Add(s);
            }

            private static void sliceRemovedHandler(Slice s)
            {
                Debug.WriteLine("dbg:sliceRemovedHandler:" + s.ToString());
                slices.Remove(s);
            }
        }
    }

    Why is the GUIClient removed?
    Program output minus compiler and FlexLib debug statements:
    dbg:radioAddedHandler:1514-3154-6500-6354
    dbg:radio found:1514-3154-6500-6354
    dbg:connect:
    dbg:connect:connected to1514-3154-6500-6354
    dbg:guiClientAdded:D793F854-AB48-4BA9-9D05-DE6ED73287A2 True 2313758720 testFlexV3_2  True True
    dbg:panAdapterAddedHandler:Flex.Smoothlake.FlexLib.Panadapter
    dbg:sliceAddedHandler:0: 14.100000 USB [100,2800]
    dbg:guiClientRemovedHandler:D793F854-AB48-4BA9-9D05-DE6ED73287A2
    (removed prior to the disconnect.)
    dbg:testing done (disconnect)
    dbg:sliceRemovedHandler:0: 14.100000 USB [100,2800]
    dbg:panAdapterRemovedHandler:Flex.Smoothlake.FlexLib.Panadapter

  • Mark_W3II
    Mark_W3II Member ✭✭✭
    edited January 2020
    This is caused because you are not setting Station name.
    The parsing logic for GUIClients assumes there is a station name.
    Immediately after connect call the following.

    theRadio.SetClientStationName("TESTSTATION");

    Now you will see the gui client object show up due to discovery, be removed then show up again due to connection with additional properties set.

    ALSO:
    You should not be adding or removing radio objects from the API.RadioList list.
    This list is maintained by the FlexAPI DLL.
    Remove the handler below or minimally remove the Add to the RadioList 


       private static void radioAddedHandler(Radio r)
            {
                Debug.WriteLine("dbg:radioAddedHandler:" + r.Serial);
                API.RadioList.Add(r);
            }
  • Jim Shaffer
    Jim Shaffer Member ✭✭
    edited January 2020
    Thanks Mark.  I'm not sure where that use of API.RadioList came from.  I really do know better than that.

Leave a Comment

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.