I'm encountering an issue where I'm trying to trigger a Python script in the background upon plugging in up to four USB devices, all with the same USB vendor and product IDs.
To accomplish this, I've created a udev rule in /etc/udev/rules.d/myrule.rules
as follows:
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1234", ATTR{idProduct}=="5678", ENV{SYSTEMD_WANTS}="usb-trigger.service"
1234 and 5689 are just examples.
Additionally, I've set up a systemd service in /etc/systemd/system/usb-trigger.service
with the following configuration:
[Unit]
Description=USB Trigger Service
[Service]
Type=oneshot
ExecStart=/path/to/my/python/script/uart.py
[Install]
WantedBy=multi-user.target
However, the script is sometimes executed and sometimes not. Furthermore, if I plug in more than the first device or the second device, the background script fails to start. Occasionally, none of the devices work as expected.
The primary goal of my Python script is to generate a CSV file upon plugging in a USB device, save the data, and close the file when the device is unplugged. I need this script to handle up to four devices.
Here's the Python script I'm using:
python
import serial
import serial.tools.list_ports
import time
import csv
import datetime
import sys
def get_current_time():
current_time = time.time()
milliseconds = int((current_time - int(current_time)) * 1000)
formatted_time = time.strftime("%H:%M:%S", time.localtime(current_time))
formatted_time += f".{milliseconds:03d}" # Adding milliseconds
return formatted_time
def write_to_csv(writer, data):
try:
writer.writerow(data)
except Exception as e:
print(f"Error writing to CSV: {e}")
def find_com_port():
try:
com_ports = serial.tools.list_ports.comports()
for port in com_ports:
if port.device.startswith('/dev/ttyUSB') or port.device.startswith('/dev/ttyACM'):
return port.device
except Exception as e:
print(f"Error finding COM port: {e}")
def main():
try:
while True:
com_port = find_com_port()
if com_port is not None:
print(f"COM port found: {com_port}")
break # Exit the loop once a COM port is found
else:
print("No COM port found. Retrying...")
time.sleep(1)
if com_port is None:
print("No COM port found.")
return
filename = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + ".csv"
bottle_id = None
bottle_id_collected = False # Flag to track if bottle ID has been collected
with serial.Serial(port=com_port, baudrate=460800, timeout=2) as ser, open(filename, 'w', newline='') as file:
print(f"Connected to {com_port} successfully.")
writer = csv.writer(file)
while True:
received_bytes = ser.readline().decode('ascii', errors='replace').strip()
if received_bytes:
if not bottle_id_collected and 'Bottle ID' in received_bytes:
bottle_id = received_bytes.split('Bottle ID')[1].strip()
writer.writerow(['Bottle ID', bottle_id])
writer.writerow(['Input 1', 'Input 2', 'Input 3', 'time stamp'])
bottle_id_collected = True
else:
parts = received_bytes.split(', ')
try:
numbers = [float(part) for part in parts]
data_row = numbers + [get_current_time()]
writer.writerow(data_row)
print(f"Writing to CSV: {data_row}")
file.flush() # Force flushing
except ValueError as e:
pass
time.sleep(0.01)
except serial.SerialException as e:
print(f"Error opening serial port {com_port}: {e}")
except KeyboardInterrupt:
print("Program terminated by user.")
except Exception as e:
print(f"An error occurred: {e}")
finally:
try:
if 'ser' in locals() and ser.is_open:
ser.close()
except Exception as e:
print(f"Error closing serial port: {e}")
try:
if 'file' in locals() and not file.closed:
file.close()
except Exception as e:
print(f"Error closing CSV file: {e}")
sys.exit()
if __name__ == "__main__":
main()
Any insights into why the script behaves inconsistently and how I can ensure it runs reliably upon plugging in multiple USB devices would be greatly appreciated. Thank you!
I configured a udev rule and systemd service to trigger a Python script upon plugging in multiple USB devices with identical IDs. I expected the script to reliably generate a CSV file for each device, handling up to four devices simultaneously. However, the script sometimes failed to start, especially with multiple devices plugged in, leading to inconsistent behavior.
systemd status usb-trigger
andjournal -xeu usb-trigger
? It might be useful if you edit that information into the question.udev
probably won't do what you want, a lot of functionality has been removed from it. See unix.stackexchange.com/a/752032 for more details.