Embedded Python Block

Allows you to create a new (custom) block in Python without needing to make and install an Out of Tree Module (OOT). When you add the block to your flowgraph, the pre-populated code simply takes the input stream and multiplies it by a constant. Note that the structure of this Python block matches the structure of an Out of Tree Module (OOT) Python block. It's essentially a Python OOT block built into a grc flowgraph.

Initial code in the Python block
Here is the pre-populated code: """ Embedded Python Blocks:

Each time this file is saved, GRC will instantiate the first class it finds to get ports and parameters of your block. The arguments to __init__ will be the parameters. All of them are required to have default values! """

import numpy as np from gnuradio import gr

class blk(gr.sync_block): # other base classes are basic_block, decim_block, interp_block """Embedded Python Block example - a simple multiply const"""

def __init__(self, example_param=1.0): # only default arguments here """arguments to this function show up as parameters in GRC""" gr.sync_block.__init__(           self,            name='Embedded Python Block',   # will show up in GRC            in_sig=[np.complex64],            out_sig=[np.complex64]        ) # if an attribute with the same name as a parameter is found, # a callback is registered (properties work, too). self.example_param = example_param

def work(self, input_items, output_items): """example: multiply with constant""" output_items[0][:] = input_items[0] * self.example_param return len(output_items[0])

User notes
Important: It is highly recommended that any flowgraph using an Embedded Python Block be placed in a separate directory (folder); particularly so if more than one Embedded Python Block is used in the same directory. This is because the generation process creates a file epy_block_0.py from that flowgraph. If you generate a different flowgraph in the same directory, its Embedded Python Block will overwrite the file. Warning: To make changes to the Python code, you must follow the steps above. If you edit the epy_block_0.py file directly and then generate the flowgraph again, your changes will be wiped out! (The most recent edited code is actually stored in the .grc file.)
 * To revise the Python code:
 * right click on the Embedded Python block
 * select Properties
 * select Open in Editor
 * select Use Default or Choose Editor
 * For some platforms the Use Default button may do nothing; see below.
 * if you select Choose Editor, the /usr/bin folder will open for you to pick one.
 * When you have finished editing, save the file (usually Ctrl-S).
 * close the edit window.
 * If there are any syntax errors, they are shown in the Properties window.
 * select OK . It is not necessary to select Apply.
 * to change the default editor (works for Debian):
 * open File Manager
 * single right click a file of type .py
 * left click on 'Properties'
 * click on the pull down for 'Open with:'
 * click on the editor of your choice
 * click OK

Parameters
The parameters for this block are simply those of your embedded Python block itself.

Note that every parameter needs a default value. For example, in the code above, note line: def __init__(self, example_param=1.0): # only default arguments here   If you don't have any parameters, change that line of code to def __init__(self):

If you have a vector length equal to a variable of your block, note that the default value must be "hardcoded".

Example Flowgraph
This flowgraph shows how an Embedded Python Block can be used to convert a string from a Message Edit Box to a byte string for the output port. The text is sent through a Throttle to a Text Sink, which is an OOT module. See gr-display.





This is the epy_block_0.py code: """ Embedded Python Block demo """


 * 1)  epy_block_0.py
 * 2)  created 10/17/2019

import numpy as np from gnuradio import gr

import pmt

textboxValue = ""

class my_sync_block(gr.sync_block): """   reads input from a message port    outputs text    """ def __init__(self): gr.sync_block.__init__(self,           name = "Embedded Python demo",            in_sig = None,            out_sig = [np.byte]) self.message_port_register_in(pmt.intern('msg_in')) self.message_port_register_out(pmt.intern('clear_input')) self.set_msg_handler(pmt.intern('msg_in'), self.handle_msg)

def handle_msg(self, msg): global textboxValue

textboxValue = pmt.symbol_to_string (msg) # print (textboxValue) def work(self, input_items, output_items): global textboxValue

# get length of string _len = len(textboxValue) if (_len > 0): # terminate with LF           textboxValue += "\n" _len += 1 # store elements in output array for x in range(_len): output_items[0][x] = ord(textboxValue[x]) textboxValue = "" self.message_port_pub(pmt.intern('clear_input'), pmt.intern('')) return (_len) else: return (0)

Another example can be found in https://github.com/duggabe/gr-morse-code-gen