# Trouble creating simple custom Sink (Python): Unable to coerce endpoint

**URL:** <https://www.ruby-forum.com/t/trouble-creating-simple-custom-sink-python-unable-to-coerce-endpoint/242863>\
**Category:** GNU Radio\
**Created:** [August 3, 2015, 8:06pm UTC](https://www.ruby-forum.com/t/trouble-creating-simple-custom-sink-python-unable-to-coerce-endpoint/242863 "2015-08-03T20:06:33Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [August 3, 2015, 8:06pm UTC](https://www.ruby-forum.com/t/trouble-creating-simple-custom-sink-python-unable-to-coerce-endpoint/242863/1 "2015-08-03T20:06:33Z")

</div>

I’d like to implement a simple custom sink block in Python.

AFAIK, a sink is a 1:0 basic block, with one input port, and no output  
port.

I define it as a class:

class MySink(gr.basic\_block):  
def **init** (self, src\_block):  
gr.basic\_block. **init** (self, name=‘MySink’,  
in\_sig=[numpy.float32],  
out\_sig=None)  
gr.top\_block().connect(src\_block, self)

Then, in the top block constructor:  
# …  
self.gsm\_fcch\_detector\_0 = grgsm.fcch\_detector(4)  
# Line bellow raises an ‘Unable to coerce endpoint’ exception  
self.my\_sink = MySink(self.gsm\_fcch\_detector\_0)

As you may already have guessed, I’m a newcomer here, and I’m sure I  
miss something obvious.  
I thought the connect line should wire the FCCH detector output port to  
my custom sink input port, but instead it raises an exception.

I will really appreciate any direction, as I’m a bit stuck here: could  
someone point me toward what I clearly misunderstand ?

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 3, 2015, 8:16pm UTC](https://www.ruby-forum.com/t/trouble-creating-simple-custom-sink-python-unable-to-coerce-endpoint/242863/2 "2015-08-03T20:16:29Z")

</div>

Hi M4RL0V,

a sink is typically built as a sync block, simply because it’s easier  
(and still works), since you don’t have to implement a general\_work (and  
a forecast).

So your problem here is that logically, connecting happens in the  
top\_block, not in the block itself; have a look at python code that the  
GNU Radio Companion generates when connecting two blocks. It simply  
happens outside any constructor as tb.connect(source,sink).

Generally, I don’t know whether that actually is the problem here. You  
forgot to actually include information on what goes wrong, and any  
relevant errors (if any). It’s hard to help you like this 🙂 Here’s a  
link having a few tips on how to ask good questions on the mailing list:  
[https://gnuradio.org/redmine/projects/gnuradio/wiki/ReportingErrors](https://gnuradio.org/redmine/projects/gnuradio/wiki/ReportingErrors)

Best regards,  
Marcus

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 4, 2015, 3:41am UTC](https://www.ruby-forum.com/t/trouble-creating-simple-custom-sink-python-unable-to-coerce-endpoint/242863/3 "2015-08-04T03:41:37Z")

</div>

Marcus, Thank you for your answer.

> a sink is typically built as a sync block, simply because it’s easier  
> (and still works), since you don’t have to implement a general\_work (and  
> a forecast).

Actually, I do not override general\_work() neither forecast(), but only  
work(), with signature:  
work(self, input\_items, output\_items)

Though the default forecast() implementation (1 input → 1 output) may  
be wrong for me (as I don’t have any output), and my work function does  
not call consume(), I do not think this may cause the error, since the  
ValueError(“Unable to coerce endpoint”) exception raises at:  
self.connect((self.gsm\_fcch\_detector\_0,0) , (self.my\_sink, 0))

I assume self.gsm\_fcch\_detector\_0 is properly initialized, as when I  
substitute the code bellow, it works as expected:  
self.connect((self.gsm\_fcch\_detector\_0, 0), (self.blocks\_tag\_debug\_0,  
0))  
where blocks\_tag\_debug\_0 is of type gr.blocks.tag\_debug.

Following your suggestion, I updated my code to inherit from sync\_block  
rather than basic\_block:  
class MySink(gr.sync\_block):  
def **init** (self) gr.sync\_block. **init** (self, name=‘MySink’,  
in\_sig=[numpy.float32], out\_sig=None)

In my understanding, this should define a sink block with a single input  
port with item size float32, and no output port. But still the same  
error.

\< So your problem here is that logically, connecting happens in the  
\< top\_block, not in the block itself; have a look at python code that  
the  
\< GNU Radio Companion generates when connecting two blocks. It simply  
\< happens outside any constructor as tb.connect(source,sink).

I use GNU radio 3.7, and companion generates Python scripts which  
initialize the whole flow graph in the top block constructor, that  
contains sections for Parameters and Variables, then Blocks, and then  
Connections. The main() function only instantiates and  
starts/stops/waits the top block (no connection happen here for me).  
I still tried to call connect() from the main() function rather than  
from the top block constructor, the error is identical.

\< Generally, I don’t know whether that actually is the problem here. You  
\< forgot to actually include information on what goes wrong, and any  
\< relevant errors (if any). It’s hard to help you like this 🙂

I’m not sure I can tell you more that this: connecting an input to my  
stupid sink raises ValueError(“Unable to coerce endpoint”).  
Bellow is the console output:

gr-osmosdr v0.1.4-48-g86ad5842 (0.1.5git) gnuradio 3.7.7.1  
built-in source types: file fcd rtl\_tcp bladerf rfspace  
Opening nuand bladeRF with device identifier string: “\*:instance=0”  
Serial # 23a1…fec4  
FW v1.8.0 FPGA v0.3.3  
[INFO @ bladerf.c:648] Clamping bandwidth to 1500000Hz  
Using Volk machine: avx\_64\_mmx\_orc  
Traceback (most recent call last):  
File “./fcch\_block.py”, line 101, in   
tb = fcch\_block(ppm=options.ppm, fc=options.fc)  
File “./fcch\_block.py”, line 65, in **init**  
self.connect((self.gsm\_fcch\_detector\_0,0) , (self.my\_sink, 0))  
File  
“/rand/platform/gnuradio-3.7.7.1/lib/python2.7/dist-packages/gnuradio/gr/hier\_block2.py”,  
line 48, in wrapped  
raise ValueError(“Unable to coerce endpoint”)  
ValueError: Unable to coerce endpoint

I understand the runtime complains that the (self.my\_sink,0) port is not  
defined (can not be coerced), and thus can’t connect to the source  
output port, though I assumed providing the appropriate input I/O  
signature to the sink block’s constructor should achieve its input  
port’s “registration”.

Thanks again for your kind help.
