The Raspberry PI seems to be dropping the connection to (some?) paired devices after 5-15 minutes of running a python script.
The Connection can be recreated with this shell command:
bluetoothctl
But to enter this command, the script would have to be killed and restarted afterwards.
Attention: After testing this approach for a while I found out it didn't fix the problem in general
NOT WORKING:
Although I didn't test running my program for several hours, this seems to do the trick.
from threading import Thread
from time import sleep
import subprocess
def bluetooth_stay_awake():
"""Ping the bluetooth compontent to keep all connections up"""
thread= Thread(target=(lambda:subprocess.run(["watch", "bluetoothctl"])))
thread.start()
Using the shell command watch bluetoothctl is important here, otherwise the bluetoothctl process would block you python script.
Shell Commands & Threading in Python
Related
I'm trying to automate the restarting of several servers running in iTerm2 tabs using iTerm2's Python API. I can get a reference to the sessions, and issue commands to them (with async_send_text), but I can't figure out how to send SIGINT signals to them so I can issue the restart commands.
I've seen a few answers using AppleScript, but it seems like this should be possible in python.
You can use os.kill() to send signals to a process as long as you have the process ID:
import os
import sys
os.kill(<PID>, signal.SIGINT)
This should work even when the process is in running in a terminal emulator.
Hardware setup (computer, etc)
Ubuntu server 18.04.1
Serial To Usb Converter with 8 ports
Python version
2.7.15r1
Python program description
When the program starts to create some threads:
Create one thread for the Modbus server.
Run 1 thread for each serial port connected (/dev/ttyUSBn) and start read the data.
Problem explanation
When I run the script using the normal command (python2.7 myProgram.py) it work, so the modbus server start and I can read the value, and I can also see the usb-serial convert blink on the TX-RX leds.
If I check the readed data they are correct, so the program is working properly.
The problem come out when I set up a crontab job that run my python script!
The modbus server start properly, but I can't see the usb-serial converter leds blink and the python program don't print the readed data. That means the program is not working on the "serial" side.
To create the job I has used the following commands:
crontab -e
selected nano (default option)
added at the end of the file the cron command: #reboot /usr/bin/python2.7 /myProgram.py
I can't figure out where the problem is, the program is not catching the exception and the process is still running until I stop it manually. If I stop it and run it manually after that it start and work properly.
To help you:
I have also tried to run it using **systemctl**, the problem is the same.
At boot the service start and if I check it I can read: Active(running), but the software is not reading from the serial port.
The questions are:
How can I solve it?
There is something wrong with the crontab job?
Maybe crontab job can't access the /dev/ directory? How can I solve this?
I'm very confused about that, I hope the question is properly created and formatted.
EDIT 30/11/18:
I have removed the crontab command, and create a service to run the program using this procedure.
If I run the command: service supervision start I can see that the process is running correctly and on htop I have only 4 processes.
In this case, the program is not reading from the serial port, but the modbus server is working. You can see that I have just 4 processes and the cpu load is too high.
If I run it manually with the command: python2.7 LibSupervisione.py
The output of the htop command is:
Here you can see that I have more processes, 1 for each thread that I create and the load on the cpu is properly distributed.
Your script probably requires a Console or some Environment variables, but in a systemd started process you dont have these automatically.
The easiest way would be to prepend /usr/bin/bash -c "your command" in your System unit in the field ExecStart to enable a Shell like Environment likle this:
ExecStart=/bin/bash -c "/usr/bin/python2.7 /myProgram.py"
WorkingDirectory=yourWorkingDir
Why do you Need to use cron? Use a systemd timer instead.
If you could run your code with the service like this: sudo service <service-name> start and get a good status using sudo service <serivice-name> status, you can test it in crontab -e like this (run every 5 minutes for test):
*/5 * * * * service <service-name> start
*/10 * * * * service <service-name> stop
Then using #rebote after with the above test.
OR:
Finally, if you want to run your code/service at the system startup, do it instead of cron jon:
Edit the rc.local file with an editor with the sudo permission, then:
#!/bin/sh -e
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
service <service-name> start
exit 0
[NOTE]:
This is the procedure of creating a service from your code.
My question regards SSH on Raspberry Pi.
I am able to successfully ssh on to the Pi using the command:
sudo ssh pi#<ipaddress>
and then entering the password.
Let's say I have a Python script file on the Pi that I execute over SSH. Let's say the script reads:
import time
while True:
print('Hello')
time.sleep(1)
This will print 'Hello' every second whilst the terminal/command prompt window is still open (that is, the computer I am using to access the Pi is running and the SSH session remains open). If I close the connection, then the code will stop being executed on the Pi.
Is there a way I can use SSH to keep the code running on the Pi even when I close the window running SSH on the computer I am using to access the Pi? As in the Pi will keep printing 'Hello' even after I shut down my computer. Maybe by entering a command to open a terminal window on the Pi itself and running the script in that terminal window?
Is there a way this can be done?
Thanks
There are two options I can think of:
create a cron job. This method is usually used to execute scripts/programs repeatedly. The job is triggered by the cron program, so it doesn't matter whether or not you are connected to the Pi, as long as it runs. You just have to connect once and setup the job (typically using crontab -e).
use screen (on Wikipedia) or tmux (on Wikipedia). Those are called terminal multiplexers, and allow you to keep shells (and thus any script/program) running although you aren't connected. Note that, in this case, you will have to manually start your script each time, so this solution is well-suited to scripts that run for a long time but are not started too often.
I am running a python process (through Django's manage.py) that will take about 6 days to complete. I would start it through an SSH tunnel, but that would require me to keep my Terminal window running and not let my computer fall asleep so the connection stays intact.
While the process is running, it reports the percentage on a single line (by replacing the line over and over again).
How can I start the process and be able to disconnect from SSH, but still be able to check on its progress when I reconnect?
use GNU Screen, your life will be so much more beautiful when you could load/reload your working session of terminals anytime you want --- they never die, and yet they ain't no zombies.
This is not really a Python question, rather an OS question.
So what you can do in linux is run your process with no hang up.
tmp.py
import time
for i in range(10):
print i
time.sleep(1)
No you can run it like so:
sudo nohup python -u tmp.py >> output &
The output will be placed in this file.
Then you can watch the output comming to the file by doing
tail -f output
When I open Python's IDLE, sometimes and error name 'port binding error' is accrues, and IDLE is filed to run on the computer. one this error accrues, it will repeat every time I'll open IDLE, till the computer will be restarted. the error box saies: ' ILDE can't bind to a TCP/IP port, which is necessary to communicate with its Python execution server. This might be because no networking is installed on this computer. Run IDLE with the -n command line switch to start without a subprocess and refer to help/IDLE Help 'Running without a subprocess' for further details.'
WTF?
Every command you type into the idle
after >>> will usually be sent to another subprocess that executes it => the UI can do what it wants, the user can do as he/she likes. If you use Tkinter to create your own GUI, this can prevent you from crashing the IDLE windows.
IDLE uses port 3000 I think. It could be that there is something listening there for connections other than the subprocess.
in the folder of idlelib:
import idlelib
print idlelib.__file__
there is the idle.py, idle.pyw and idle.bat that can be started with -n to not make a new subproces.
I hope your WTF is answered.