0

I have a program, which needs to continuously run in the background, but be able to receive instructions to change. I have this thread running, which sends data to an Arduino and receives data back:

class receiveTemp (threading.Thread):
    def __init__(self, out):
        threading.Thread.__init__(self)
        self.out = out

    def run(self):
        self.alive = True
        try:
            while self.alive:
                rec = send("command")
                self.out.write(rec)
        except BaseException as Error:
            print(Error)
            pass

Now I need to change the command I send with an external program.
I tried using Pyro4, but I can not seem to get a Thread running on the server and then controlling it with the client.

Any ideas?

  • You're looking for the buzz phrase "Interprocess Communications". Research how it's done in C, since that's what most of the innards of python is based on. Among other options, you can do this with sockets, pipes, shared memory, or possibly (if what you want to send is limited enough), a signal handler. – Scott Mermelstein Jan 26 '17 at 16:09
  • What was the problem getting a "tread running on the server" using Pyro4? As soon as you start the requestloop of a Pyro4 daemon, it's running a server process that processes requests in worker threads. – Irmen de Jong Jan 27 '17 at 19:31

1 Answers1

2

Scott Mermelstein's advice is good, I hope you will look into interprocess communications. But as a quick example to get you started, I would suggest modifying your code like this:

import threading
import queue
import sys
import time

class receiveTemp (threading.Thread):
    def __init__(self, out, stop, q):
        threading.Thread.__init__(self)
        self.out = out
        self.q = q
        self.stop = stop

    def run(self):
        while not self.stop.is_set():
            try:
                cmd = self.q.get(timeout=1)
            except queue.Empty:
                continue
            try:
                rec = send(cmd)
                self.out.write(rec)
            except BaseException as Error:
                print(Error)
                pass

stop = threading.Event()
q = queue.Queue()

rt = receiveTemp(sys.stdout, stop, q)
rt.start()

# Everything below here is an example of how this could be used.
# Replace with your own code.
time.sleep(1)
# Send commands using put.
q.put('command0')
q.put('command1')
q.put('command2')
time.sleep(3)
q.put('command3')
time.sleep(2)
q.put('command4')
time.sleep(1)
# Tell the thread to stop by asserting the event.
stop.set()
rt.join()
print('Done')

This code uses a threading.Event as a signal to the thread that it should stop. It then uses a queue.Queue as a way to send commands to the thread from outside. You will need to use q.put(command) to add commands to the queue from outside the thread.

I didn't test this with an Arduino, I created my own version of send for testing that just returned the command.

FamousJameous
  • 1,565
  • 11
  • 25