Getting started at the Application end


#1

Hi Guys,

I’ve just started on Nameko and I think maybe the problem I’m having is unfamiliar vocabulary. I hope you’ll bear with me or point me in the right direction.

I have two issues that I’m trying to understand.

  1. I have a serial device attached to a small computer (Raspberry Pi), and I want to keep the connection from the device to the Pi open, once it’s opened through eg ttyUSB0. It will return a “Serial” object that I wish to be persistent on the Pi. The Raspberry Pi’s sole function is to run the device handler service. I wanted to have a global variable holding it on the Pi Service, but the Methods didn’t seem to be able to see it. Like this:
    class Arduino(object):
        
        name = "Arduino_service"
        test=0
        
        # Initialise Arduino
        @rpc
        def connect(self):
            # Set serial port to 0
            self.ser = 0
            test=test+1
            print (test)

Gives me:

File "./ArduinoService.py", line 19, in connect
    test=test+1
UnboundLocalError: local variable 'test' referenced before assignment
  1. The second problem is how to access the code from my main application:

I thought I could do this:

    Arduino = json.loads(n.rpc.Arduino_service.connect())

But apparently not. No error, nothing. Do I need to use a framework like Flask to do it for me?

Regards

Steve

PS Is there a way of formatting code on this board?


#2

Hi Steve,

There’s a few things going on here, but the main one is that a Nameko service doesn’t behave exactly like a normal Python class (even though it looks like one).

As it happens I just spoke about this at a meetup. Check the video here for a quick overview.

After you’ve watched that, this recommendation will make sense:

Don’t use your service class to store state, even class-level attributes. If you want your service to read or write to the serial device, you should wrap it in a DependencyProvider. If you want your service to act on signals from the serial device, you should use an Entrypoint. Maybe your use-case needs both.

In the code you’ve posted, test=test+1 is throwing because test is an unbound local. Arduino.test=Arduino.test+1 or self.test=self.test+1 would not throw, but see above – don’t store state on your service instance or class.

Does that make sense?

PS. I edited your post to correct the formatting. Open the editor yourself to see how it’s formatted (It’s just Markdown)