From: Dave B. <g8k...@go...> - 2025-03-30 11:57:50
|
Steve. If you've already got "rigctld" open as a daemon in the background, you do not need to issue "rigctl" commands, just open a TCP socket to the daemon, and issue commands, and receive status replies via that route. rigctld and rigctl are different animals. You can have also more than one rigctld running, listening on different TCP/IP ports, for different radio's. As Erik wrote, they can even be on a different machine, so long as the address/port is accessible from "your" machine, the radio and it's local computer (even a Pi) could be the other side of the planet if needed. Python is very network friendly in that way, and it works very well too. "localhost:port" is your friend... This crude code below, is what I used a while ago to get the old FT-736r to appear as a readable radio, to keep gpredict happy back in the hamlib 3.3 days. No longer needed with hamlib 4.x ------------------------------------------------------------------------ import socket def Main(): # Local temporary string storage. subfreq = "435000000" mainfreq = "145000000" # GPredict side host:port # Well away from any default Hamlib port. gphost = 'localhost' gpport = 50000 # HamLib side host:port # Well away from any default Hamlib port. hlhost = 'localhost' hlport = 50736 # Create a Server socket for GPredict to connect to as a client. gpSocket = socket.socket() gpSocket.bind((gphost,gpport)) gpSocket.listen(3) print ("FT-736 Helper listening on port " + str(gpport)) # Create a Client socket, to connect to the HamLib server. # NOTE! rigctld MUST be started before this script is run! # Like this... # $ rigctld -m110 -r /dev/ttyUSB4 -s 4800 -T localhost -t 50736 # (post HamLib 4.x use -m1010 for the model number.) while True: gpconn, gpaddr = gpSocket.accept() # print ("Connection from: " + str(gpaddr).rstrip()) # The Hamlib backend will automatically have done this, but it # will be needed if we turn CAT off, when Gpredict "Disengages" # and we later "Engage" the radio. # Not needed for Hamlib 3.3 or later, it does the right thing # by default. # hlcmd = "w \\0x00\\0x00\\0x00\\0x00\\0x00\n" # print ("Sending " + hlcmd) # hlSocket.sendall(hlcmd.encode()) # NOTE! If this is used, rigctld "Expects" a reply from the rig, # that will never arrive. So there will be a delay of some 2 seconds # or more before it returns to us. hlSocket = socket.socket() hlSocket.connect((hlhost,hlport)) print ("Linked to rigctld") while True: gpcmd = gpconn.recv(1024).decode() if not gpcmd: break print ("From Gpredict: " + gpcmd.rstrip()) if gpcmd[0] == "F": # Set Main frequency: Remember the value. mainfreq = (gpcmd[1:]).lstrip() # code here to send to Hamlib hlSocket.sendall(gpcmd.encode()) reply = hlSocket.recv(1024).decode() # print ("To Gpredict: " + reply.rstrip()) gpconn.sendall(reply.encode()) elif gpcmd[0] == "I": # Set Sub frequency: Remember the value. subfreq = (gpcmd[1:]).lstrip() # code here to send to Hamlib hlSocket.sendall(gpcmd.encode()) reply = hlSocket.recv(1024).decode() # print ("To Gpredict: " + reply.rstrip()) gpconn.sendall(reply.encode()) elif gpcmd[0] == "f": # fake read of the main frequency reply = mainfreq + "\n" # print ("To Gpredict: " + reply.rstrip()) gpconn.sendall(reply.encode()) elif gpcmd[0] == "i": # fake read of the sub frequency reply = subfreq + "\n" # print ("To Gpredict: " + reply.rstrip()) gpconn.sendall(reply.encode()) elif gpcmd[0] == "q": print ("Unlinking from rigctld") # hlcmd = "w \\0x00\\0x00\\0x00\\0x00\\0x80\n"ri # See earlier notes at lines 45 and 55. hlSocket.sendall(gpcmd.encode()) # or hlcmd else: hlSocket.sendall(gpcmd.encode()) reply = hlSocket.recv(1024).decode() # print ("To Gpredict: " + reply.rstrip()) gpconn.sendall(reply.encode()) gpconn.close() if __name__ == '__main__': Main() ------------------------------------------------------------------------ Heck, if I can do it, etc... No need to comment on bad Python practices, this was all my own work mistookes included, but it worked very well indeed. As above, no longer needed for the Hamlib 4.x, the local frequency memory is now implemented within the hamlib backend for the 736, and also it keeps the rig CAT port open between so long as at least one application itself stays connected to that instance of rigctld (if just to avoid the annoying beeps from the rig!) I could never find a reliable way to detect if the needed daemon was already running and if not, start it from within Python, though I'm sure it can be done, just the doc's are somewhat impenetrable to someone who is not a pro snake charmer!. That code was itself invoked from a bash script that started the daemon, started the Python helper tool, and then launched Gpredict. Killing stuff off in the reverse order, when Gpredict was itself exited/ended. Best of all, it is entirely cross platform, others used it on various Windows machines, while I was doing this on Linux. 73. Dave G0WBX. On 30/03/2025 08:53, Stephen Pattinson via Hamlib-developer wrote: > Hi Erik, > Thanks for responding. > My Python 3 app is starting rigctld effectively in the background > using the subprocessPopen() mechanism. Then to retrieve parameters > from the radio, it is running subprocess.Run() which effectively > executes "rigctl -m 2 f" for example to get the VFO frequency by > capturing the response, but firing off a windows EXE program every > second is pretty awful. I assumed I could via the API I assumed was > available, open a channel/pipe/whatever and effectively do what ever > rigctl is doing internally. > I've looked at the API references and web pages, but they seem > convulsively C. I see tantalizing references to python bindings (I'm > not sure what that means) and in the Debian world I see a > python3-hamlib library, but of course I'm looking for a Windows solution. > Am I looking for something that doesn't exist Erik? > 73 Steve > VK3SPX > > > On 30/03/2025 18:32, Erik Icket wrote: >> Hi Steve, >> >> One way to obtain a better segregation between your Python app and >> the rig, >> is to go via the rigctld daemon. >> Once the daemon runs (local or remote), you may open a socket to it and >> issue your commands. >> For example, to know the frequency, just issue a write to socket with >> "f\n" >> contents. >> >> It is not a straight program to rig interface, as you are looking for. >> However, it does not require to launch the rigctl app each time you >> issue a >> command. >> >> g'day ! >> Erik >> ON4PB >> >> -----Original Message----- >> From: Stephen Pattinson via Hamlib-developer >> <ham...@li...> >> Sent: Saturday, 29 March 2025 09:06 >> To: ham...@li... >> Subject: [Hamlib-developer] Python API >> >> Hi, >> I have written a Python (3.12.3) to talk to my IC7300 via Hamlib >> (V4.6.2) in a Windows 10 environment, but I'm just issuing "rigctl" >> commands and capturing the response. This works fine, but it's rather >> crude. >> Of course I would like to use the API which I believe is available, >> but I >> cannot find how to download the necessary additional software or >> library, or >> find the documentation for the Python API. >> I have looked at >> "https://hamlib.sourceforge.net/manuals/4.3/index.html", but this seems >> exclusively C Ironically, the most pertinent info I retrieved from a >> search >> is from the Google AI (Sigh!) which suggests I need "hamlib-python", >> but I >> can't find where the AI has scooped up this information. >> If anybody can point me at installation instructions and >> documentation for >> the API, I would be grateful. >> Thanks/73 >> Steve VK3SPX >> >> >> _______________________________________________ >> Hamlib-developer mailing list >> Ham...@li... >> https://lists.sourceforge.net/lists/listinfo/hamlib-developer >> > > > > _______________________________________________ > Hamlib-developer mailing list > Ham...@li... > https://lists.sourceforge.net/lists/listinfo/hamlib-developer |