0

I have a long script that runs several GPIO devices using both SMBus and pigpio. It starts a thread to cycle through a series of screens on an OLED display, and then connects to Paho MQTT, and keeps track of events with logging for later debugging.

There is a 'master program' called mybox.py which then uses the much larger script via:

from BIG import Box
box = Box('my box', use_WiFi=True)
box.new_OLEDi2c('my oled')
# box.start_MQTT()

from IDLE:

When I run mybox.py with IDLE everything works as planned. It spews out messages and then stops with the familliar >>>

I can then type box.start_MQTT() in IDLE and that will happen. I can continue interacting with the Box object through IDLE as long as I like.

from Terminal:

When I open a terminal and type python mybox.py it starts the same way, but then I loose the ability to interact via the terminal. If I type, it is echoed to the screen, but it doesn't go anywhere. Also cursor characters are echoed as ^[[A, ^[[B, ^[[C, ^[[D,

Question: I'm not a developer and I'm learning to swim here by trial and error. Is there some way to get the terminal interaction to work the same easy way as I'm able to do using IDLE?

Is there something about this behavior that sounds familliar? In the past I've been able to use the terminal the way I'd like to without problem, but I wonder if the terminal is being set to a different mode by my script somehow without me knowing about it? For example, I recently found out that typing exit in iTerm returns big red broken pipe banner. Maybe my output is causing the terminal to change state?


GOOD: copy/paste from IDLE:

INFO 2018-12-12 10:40:52 initiate OLEDi2c("my oled") 
 OLED initiated in 0.065995 seconds 
INFO 2018-12-12 10:40:52 show_image OLEDi2c("my oled") 
 showimage opened size w0 h0=(720, 405) 
INFO 2018-12-12 10:40:52 show_image OLEDi2c("my oled") 
 showimage hscale <= wscale resize size=(113, 64) 
INFO 2018-12-12 10:40:52 show_image OLEDi2c("my oled") 
 showimage conversion_method "threshold" 
Thread me!
keepgoing.isSet(): True
   Hey!!  keepgoing:  <threading._Event object at 0x72d279d0>
dwell_time:  None
self.dwell_time:  2
>>> 
>>> box.start_MQTT()
trying to connect with MQTT: 
pingable is:  True
('On Log: ', 'Sending CONNECT (u0, p0, wr0, wq0, wf0, c1, k60) client_id=Luke, I am your client')
connect status:  0
('Disconnect code: ', 0)
loop_start status: ('On Log: ', 'Received CONNACK (0, 0)') 
None('Connect code: ', 0)

BAD: copy/paste from Terminal:

INFO 2018-12-12 10:45:47 initiate OLEDi2c("my oled") 
 OLED initiated in 0.011983 seconds 
INFO 2018-12-12 10:45:48 show_image OLEDi2c("my oled") 
 showimage opened size w0 h0=(720, 405) 
INFO 2018-12-12 10:45:48 show_image OLEDi2c("my oled") 
 showimage hscale <= wscale resize size=(113, 64) 
INFO 2018-12-12 10:45:48 show_image OLEDi2c("my oled") 
 showimage conversion_method "threshold" 
Thread me!
keepgoing.isSet(): True
   Hey!!  keepgoing:  <threading._Event object at 0x73766b70>
dwell_time:  None
self.dwell_time:  2

asdf

^[[A^[[A^[[A^[[A^[[A^[[B^[[B^[[B^[[B^[[D^[[C^[[D^[[A('On Log: ', 'Sending PINGREQ')
  • Try running it from the terminal in the background with python mybox.py & note that little & on the end of the command. – Dougie Dec 12 '18 at 8:13
  • 1
    @Dougie I don't follow. Exactly what is it to run something in the background from the terminal? Where will the "&" appear exactly? – uhoh Dec 12 '18 at 8:55
  • It "forks" the process into the background and frees up your terminal to run other commands/programs. – Dougie Dec 12 '18 at 9:47
  • @Dougie oh, you mean this: askubuntu.com/a/396655/804741 got it. This question is about maintaining the ability to continue to call more box methods. I am sure I can use your suggestion in the future though, thank you! – uhoh Dec 12 '18 at 10:05
  • The way IDLE prompt works is called interactive mode. Running scripts in interactive mode has been discussed on SO, and it's not really related to the RPi. – Dmitry Grigoryev Dec 14 '18 at 7:59
1

YES! there are ways to get the terminal interaction to work (almost) the same way as in IDLE! Good job at tracking down alternative answers, but I think it's simpler than you might imagine.

There is a >>> prompt in the terminal if the terminal is running interactive python.

At the shell command line prompt in the terminal, invoke Python with the -i (interactive) option, followed by your module filename:

python -i mybox.py

This runs mybox.py and then presents the >>> prompt so you can continue to interact with the objects from mybox.py.

You can use the arrow keys as usual at the >>> prompt because python supports command line editing. This is one of the main differences between Idle and Python (in the terminal) because command line editing is implemented with the GNU Readline library in python and implemented with Python libraries in idle.

When you want to exit python in the terminal window, just type control-D at the >>> prompt, python will see EOF(end of file) and exit, then you will return to your shell prompt.

0

OK I see. There are two items:

  1. The existence of the thread was keeping things in the terminal from finishing. As soon as I blocked the call to oled.start_thread() the master program mybox.py finished quickly and the $ prompt returned to the screen (python had finished).

    That provided me with the...

  2. "duh..." moment. Of course there is no >>> in the terminal.

That's the explanation.

The answer is: execfile('mybox.py') temporarily, until I package this more nicely. Per this answer this is not safe, and should instead be handled by an adult (process of some kind). (also see answers to 1, 2, 3)

Problem solved.


update: As pointed out in this comment this is called running in interactive mode and answers to:

  • 1
    The python REPL shell is presumably implemented using readline to implement history and such (so the up and down arrows work, etc) which there will be a python module for. – goldilocks Dec 12 '18 at 5:06
  • @goldilocks yes I see what you mean. That gives me a lot to think about, thanks! – uhoh Dec 12 '18 at 10:21

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.