Welcome to the new FlexRadio Community! Please review the new Community Rules and other important new Community information on the Message Board.
Need the latest SmartSDR, Power Genius, Tuner Genius and Antenna Genius Software?
SmartSDR v3.8.19 and the SmartSDR v3.8.19 Release Notes | SmartSDR v2.12.1 and the SmartSDR v2.12.1 Release Notes
SmartSDR v1.12.1 and the SmartSDR v1.12.1 Release Notes
Power Genius XL Utility v3.8.8 and the Power Genius XL Release Notes v3.8.8
Tuner Genius XL Utility v1.2.11 and the Tuner Genius XL Release Notes v1.2.11
Antenna Genius Utility v4.1.8
SmartSDR v3.8.19 and the SmartSDR v3.8.19 Release Notes | SmartSDR v2.12.1 and the SmartSDR v2.12.1 Release Notes
SmartSDR v1.12.1 and the SmartSDR v1.12.1 Release Notes
Power Genius XL Utility v3.8.8 and the Power Genius XL Release Notes v3.8.8
Tuner Genius XL Utility v1.2.11 and the Tuner Genius XL Release Notes v1.2.11
Antenna Genius Utility v4.1.8
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.
Need technical support from FlexRadio? It's as simple as Creating a HelpDesk ticket.
Working on a Python API
Mark Erbaugh
Member ✭✭
I've had some success in using the FlexLib API .DLLs with Python 2.7.9 and PythonDotNet (not IronPython), but have come up against two issues:
1) I am trying to set the Panadapter Band property, but it doesn't seem to work.
2) I am trying to write a callback handler for the DataReady event on the IQStream and can't figure out the parameter calling convention in Python. I have successfully written other callback routines, but I think this is the first one that passes and array of data from the C# side. No matter how I declare the Python parameters to the callback, the Python program crashes with a Python exception. It may be that the Python Dot Net add-on is not capable of handling arrays in parameter passing.
I don't think these are issues with the FlexLib API, but rather with Python Dot Net. Hopefully, someone on the forum has some experience with this.
1) I am trying to set the Panadapter Band property, but it doesn't seem to work.
2) I am trying to write a callback handler for the DataReady event on the IQStream and can't figure out the parameter calling convention in Python. I have successfully written other callback routines, but I think this is the first one that passes and array of data from the C# side. No matter how I declare the Python parameters to the callback, the Python program crashes with a Python exception. It may be that the Python Dot Net add-on is not capable of handling arrays in parameter passing.
I don't think these are issues with the FlexLib API, but rather with Python Dot Net. Hopefully, someone on the forum has some experience with this.
3
Answers
-
Would you be wikmg to share your code? GitHub? I'd like to poke around a bit.0
-
Here's the code. It's designed to be used interactively from the Python prompt. I use the IDLE development environment which is based on Tcl/Tk. TextOutputWindow.py provides an output window.
*** API.PY ***
import clr
clr.AddReference("FlexLib")
from Flex.Smoothlake.FlexLib import API
from TextOutputWindow import TextOutputWindow
from System.Windows import Size
# ----------------------------------------
# ----- API Event Handlers ---------------
# ----------------------------------------
def RadioAdded(radio):
radio.MessageReceived += MessageReceived
radio.PropertyChanged += PropertyChanged
radio.IQStreamAdded += IQStreamAdded
radio.Connect()
msg_win.add('Radio Added: ' + radio.IP.ToString())
def RadioRemoved(radio):
msg_win.add('Radio Removed: ' + radio.IP.ToString())
# ----------------------------------------
# ----- Radio Event Handlers -------------
# ----------------------------------------
def MessageReceived(severity, msg):
msg_win.add('Message: ' + msg)
def PropertyChanged(sender, event):
msg_win.add('Change: %s' % event.PropertyName)
def IQStreamAdded(stream):
stream.DataReady = DataReady
msg_win.add('IQ Stream Added')
# ----------------------------------------
# ----- Panadapter Event Handlers --------
# ----------------------------------------
def DataReady(stream, data):
stream.DataReady = None
print('stream Data')
# ----------------------------------------
# ----- Utility Routines -----------------
# ----------------------------------------
sz = Size(400.0, 100.0)
def createPA():
radio = API.RadioList[0]
pa = radio.CreatePanadapter(sz)
pa.RequestPanadapterFromRadio()
pa.Band = "40"
return pa
def createIQStream():
radio = API.RadioList[0]
iq = radio.CreateIQStream(1)
iq.RequestIQStreamFromRadio()
return iq
# ----------------------------------------
# ----- main -----------------------------
# ----------------------------------------
if __name__ == '__main__':
msg_win = TextOutputWindow()
API.ProgramName = "Python"
API.RadioAdded += RadioAdded
API.RadioRemoved += RadioRemoved
API.Init()
*** TextOutputWindow.py ***
from Tkinter import *
import ScrolledText
import threading
import Queue
class TextOutputWindow(threading.Thread):
def __init__(self):
self.quit = 0
self.clear = 0
self.queue = Queue.Queue()
threading.Thread.__init__(self)
self.root = Tk()
self.root.title("FlexRadio Output")
self.start()
self.root.after(100, self.periodicCall)
def run(self):
self.root.protocol("WM_DELETE_WINDOW", self.quit_cb)
self.text = ScrolledText.ScrolledText(self.root)
self.text.pack(expand=YES, fill=BOTH)
self.root.mainloop()
def periodicCall(self):
if self.quit:
self.root.quit()
else:
if self.clear:
self.clear = 0
self.text.delete('1.0', END)
while self.queue.qsize():
try:
msg = self.queue.get()
self.text.insert(END, msg)
self.text.see(END)
except Queuy.Empty:
pass
self.root.after(100, self.periodicCall)
def quit_cb(self):
self.root.quit()
def add(self, message):
self.queue.put(message + '
')
0 -
Thanks Mark! I downloaded Python.Net from http://sourceforge.net/projects/pythonnet/?source=typ_redirect and had to force npython.exe into 32 bitness (using corflags) as I'm on a 64 bit version of windows 8.1. Once that was done I hit this issue https://github.com/pythonnet/pythonnet/issues/3 which seems to be an incompatability with .Net 4.5. I'm going to get the python.net source and see if I can compile it as someone has fixed this issue already.
0 -
pythonnet compiled and your code is running - is this the error you're seeing when you try to hook up the IQ events?
Unhandled Exception: Python.Runtime.PythonException: TypeError : cannot set event attributes at Python.Runtime.Dispatcher.Dispatch(ArrayList args)
at __Flex_Smoothlake_FlexLib_Radio_IQStreamAddedEventHandlerDispatcher.Invoke(IQStream )
at Flex.Smoothlake.FlexLib.Radio.OnIQStreamAdded(IQStream iq_stream) in d:GitHubFlexWebRemoteExternalFlexLib_v1.3.9FlexLibRadio.cs:line 2768
at Flex.Smoothlake.FlexLib.IQStream.StatusUpdate(String s) in d:GitHubFlexWebRemoteExternalFlexLib_v1.3.9FlexLibIQStream.cs:line 460
at Flex.Smoothlake.FlexLib.Radio.ParseStatus(String s) in d:GitHubFlexWebRemoteExternalFlexLib_v1.3.9FlexLibRadio.cs:line 1458
at Flex.Smoothlake.FlexLib.Radio.ParseRead(String s) in d:GitHubFlexWebRemoteExternalFlexLib_v1.3.9FlexLibRadio.cs:line 952
at Flex.Smoothlake.FlexLib.Radio.ProcessReadBuffer() in d:GitHubFlexWebRemoteExternalFlexLib_v1.3.9FlexLibRadio.cs:line 922
at Flex.Smoothlake.FlexLib.Radio.TCPReadCallback(IAsyncResult ar) in d:GitHubFlexWebRemoteExternalFlexLib_v1.3.9FlexLibRadio.cs:line 891
0 -
Larry
Why not setup a Community repo on GitHub anyway? Create an Organization and a Team giving anyone with a Verifiable Callsign and/or Community Login Read and Write access
And see what happens.
Keep it public and open and just Flow with the Go.
Beats copy pasting Community posts the Community Search can't always seem to filter out.
Not sure how to handle Admin though. Don't want it to be ruined by bad planning.
What do you think?
Anyone else?
Post some feedback.
Jay - NO5J0 -
Im thinking
Community-Development for the name of the organization.
FlexCoders for the team name
Callsign repos/folders for Sub projects from team members.
Maybe allow Admin from anyone a chosen few.
Not sure how we select the chosen few.
0 -
Hi Mark,
Good deal. I have my python code running on a BBB and it's switching my bands successfully. But now I am going back and rewriting it in PHP, I want to do a lot of interfacing with port 80, so I believe that makes sense for me. It was a blast starting to learn Python.
73,
Phil0 -
Good idea Jay - I ran with it and hope that my deed goes unpunished. I've avoided using the name Flex Radio so not to confuse people that this repo is managed by Flex Radio. I'm a novice Python coder and FlexLib user but hope to learn from you all. The Git repo is here: https://github.com/FlexCommunityDevelopment/FlexPythonAPI and I'm happy to add anyone from this list who would like to contribute. The repo is public so you can git it without permission. I've uploaded a modified version of Mark's Python code. It now supports IQ stream as he wanted (I think) and as well, pan and waterfall streams. Read the readme in the repo for hints on how to get it running. It *should* run with any Flex 6000 - I tested with a 6500. I experienced some strange behavior running this code while SmartSDR was running on the same PC - no doubt because I don't fully understand the API. Comments and criticisms welcome.0
-
Larry
I am real glad you set us on this path. Having never had Admin or ownership of a repo on GitHub I was reluctant, to jump in and set it up myself without feedback. I'll help out, if you need some spare idle hands, I'm sometimes considered trainable on most things software and know how to find my own answers. And work well in "No training budget" situations. I'm also a big fan of learn by doing. I really appreciate all the individuals doing that already. I hope anyone else that is interested in being part of a "Team" will explore the concept of jumping in too.
Remember folks it's just software you can't really break anything permanently. You don't even have to take the cover off. Take a backup "have a spare" and tweak it till it works almost the same as it did, "only better".
Now we have someplace we can look at code, find out what needs to be learned to play with the code, let others see what we try to code, and tell us what we did wrong.
Who knows, what's on the other side of that mountain, we will if we go and have a look, Thanks Larry somebody had point the way. I'll help carrying the gear.
Join the team. We might even get colander hats.
Lets all GitFlexible!
Jay - NO5J
1 -
you can't really break anything permanently
I hope that is true - I'm sure I abused my Flex 6500 with some of this code but it didn't brick - yet0 -
If you write code that forces keydown and disables the front panel reboot button. You might brick it with software. Easier to just use a hammer. Coding Hard!, Hammer Easy! I find uses for bricks too.
Jay - NO5J0 -
Mark or Larry
Starting from scratch on Win 8.1 64bit. I need to install Python 2.7.9.
I'm wondering about the 32/64 bit issue for the Python Install though.
IOW Install Python 2.7.9. Which version inflicts the least pain?
73, Jay - NO5J0 -
I'm running Wndows 7 64-bit. I installed the 64-bit version of Python. The only issue I've had so far was that the original PythonDotNet project only worked with 32-bit, but I did find a version that worked with 64 bit.
0 -
Larry,
I think I got your code running. I run Example.py and see data in the text window. One issue. When I close the text window, it seems to take the radio off-line to where SmartSDR can't see any radios. So far the only thing I've found to fix that is a power cycle.
Also, I was seeing the error you found. What did you do the get rid of that?
FWIW, I may not have much time to devote to this project until the weekend, so ignore any silence from me.
0 -
Mark
Weekends are ok by me. Now retired so every day is saturday and every night feels like .... Oh yeah no more NightLife! Sux to be old! Besides if your busy all week I get more time to learn all the stuff I used to avoid and now wish I'd taken seriously.
GitFlexAble
73, Jay - NO5J
0 -
I have modified Larry's code (his modification of my code) slightly and it seems more stable.
I added two lines to the bottom of the Quit() function:
API.RadioAdded -= RadioAdded
msg_win.quit = 1
I was having a problem that with the original code, once I quit, I had to power down the radio to get it to respond to the Python code or SmartSDR. It would respond to a ping, but that was all.
I noticed that the message window showed a Radio Removed message followed by a connecting sequence. I think what was messing up the radio was that the RadioAdded callback was still alive and it started processing the connection then the app terminated.
The msg_win.quit = 1 line merely closes the FlexRadio Output window.
0 -
It's probably just a coincidence, in trying to get set up to play with the code, starting out about the time I tried installing Python.Net, and Python 2.7.9, and shortly after having received an update from Microsoft of .NET Framework 4.5.1 Multi-Targeting Pack. things began to go south. I can't lay the blame on anything. I have things working again, and I'm looking into updateing my backup disc images. Which I have a habit of not doing. So I'll get caught up with you guys soon I hope.
Not really all that big of an issue, It's just the Flex-Box. Once i figure out how to set up the file/access permissions I'm going to setup a cron job on one of my linux boxes to rsync an incremental backup image to the TimeMachine disk attached to my wifes Imac.
So backup a Window 8.1 box on an Apple with a Linux box. Doesn't that sound like a no-brainer? TimeMachine for Windows how hard can that be to setup? It worked before.
I just never included the Flex-Box when it arrived.
73, Jay - NO5J0 -
Here's my update for Thursday. I've managed to get things sort of working. I can connect to the Flex and create a Panadapter. For some reason, creating a Panadapter automatically creates a slice. My callback that prints "Slice Created" actually gets called 3 times when I call radio.RequestPanafall. If I check SlicesAvailable and PanadaptersAvailable after that, both show 0. If I close the Panadapter, both show 2 (I have a 6300).
Some times during my testing, when I connect to the radio, it would automatically create a Panadapter as well. I cycled the power and that stopped. I wonder if the automatic creation of Panadapters and Slices has something to do with the Persistence database in the radio?
1 -
This is the sort of information I was hoping to get. Play with the API and Post what you see.
What?, Why?, and How?, are much more interesting than, When?
73, Jay - NO5J0 -
I suspect that the radio is treating the Panadapter creation as a persistence event which triggers a Slice to be created. Each of these is probably taking it's own radio resource and thus exhausts the total supply (2) on a FLEX-6300.
We have some work to do to enable better API handling for the Panadapters to prevent this sort of issue.1 -
If it is an issue with the radio, how does SmartSDR get around it?
Is there a workaround that will allow FlexLib API to be used with the 6300 and more than one Panadapter and Slice?1 -
The way the radio makes decisions about how to use the resources depends on the application name being used. Today the Panadapters do something different if connected to SmartSDR-Win. This will obviously need to change to enable more clients to use the display objects.1
-
Eric,
Thanks for the info. I learn something new every day! Would it make sense for my Python application to impersonate SmartSDR-Win? Is that even possible?
73 and have a good weekend,
Mark
1 -
Not sure if this idea would help, but, if you ID the radio first, ( 6300,6500,6700) and then set a maximum number of pans/slices for each radio according to model, then you should be able to query the api for the current number of open pans/slices and keep things under control. That is what I have had in mind since I was not sure if the software on the radio kept track of that and kept an outside application from attempting to open more pans/slices than a particular model of radio supports.
Just a thought, and if not what you were looking for, sorry!
james
WD5GWY
1 -
Things operate differently with SmartSDR on Windows than with other clients because of how the GUI needs to operate. Now that we have some folks wanting to do the same things and create GUI clients of their own, we discussed this thread and made a change today to support this. Before calling API.Init() you will want to set IsGUI to true:
API.ProgramName = "your program";
At this time, there will be only a single GUI allowed so you will not be able to run your application along side SmartSDR if you have used IsGUI (there can be only one). This change has been checked into the v1.4 codebase so it will be available starting with v1.4.
API.IsGUI = true;
API.Init();
2 -
Good to hear Steve! I have been SLOWLY working on a very simple program to control the radio, independent of SmartSDR, but, have had a few issues getting the proper initialization sequence right to set the radio up. This looks like it will make that easier. (once I get all the setting right!)
james
WD5GWY
0 -
Good catch!0
-
Mark - I did some research on Fatal Python error: PyImport_GetModuleDict: no module dictionary! and I haven't found a hint at what is causing it.0
-
Mark - I can confirm the behavior that Eric describes above. Uppon connecting to a 6500 we have four pans and four slices available as expected. When ProgramName = 'SmartSDR-Win' and you call Radio.RequestPanfall or Waterfall.RequestWaterfallFromRadio, the radio reports three pans and and three slices available once the pan and slice are created - as expected. When the API.ProgramName is anything else, there are only two slices and two pans available after initial call to RequestPanfall or RequestWaterfallFromRadio. It seems that Panadaper.RequestPanadapterFromRadio(), once the panadapter has been added, will cause the pan's DataReady events to fire. Another interesting thing to note is that when ProgramName = 'SmartSDR-Win', when I add a slice the number of available pans does not reduce. After creating a single pan and adding four slices to it I still had three pans available and I was able to create them albeit with no slices. When ProgramName is anything else, as I add slices to an existing pan, the number of pans reduces.0
Leave a Comment
Categories
- All Categories
- 289 Community Topics
- 2.1K New Ideas
- 535 The Flea Market
- 7.5K Software
- 6K SmartSDR for Windows
- 146 SmartSDR for Maestro and M models
- 360 SmartSDR for Mac
- 249 SmartSDR for iOS
- 231 SmartSDR CAT
- 172 DAX
- 352 SmartSDR API
- 8.8K Radios and Accessories
- 7K FLEX-6000 Signature Series
- 26 FLEX-8000 Signature Series
- 850 Maestro
- 44 FlexControl
- 847 FLEX Series (Legacy) Radios
- 796 Genius Products
- 416 Power Genius XL Amplifier
- 277 Tuner Genius XL
- 103 Antenna Genius
- 243 Shack Infrastructure
- 166 Networking
- 404 Remote Operation (SmartLink)
- 130 Contesting
- 631 Peripherals & Station Integration
- 125 Amateur Radio Interests
- 870 Third-Party Software