Python script read serial port, output to text file - python

I'm trying to read output from a serial port and write it to a text file. So far this connects and prints the output, but I can't figure out how to send the output to a text file (preferrable a csv file).
#! /usr/bin/env python3
import serial
import csv
import sys
import io
#excel stuff
#from time import gmtime, strftime
#resultFile=open('MyData.csv','wb')
#end excel stuff
def scan():
"""scan for available ports. return a list of tuples (num, name)"""
available = []
for i in range(256):
try:
s = serial.Serial(i)
available.append( (i, s.portstr))
s.close() # explicit close 'cause of delayed GC in java
except serial.SerialException:
pass
return available
if __name__=='__main__':
print ("Found ports:")
for n,s in scan():
print ("(%d) %s" % (n,s))
selection = input("Enter port number:")
try:
ser = serial.Serial(eval(selection), 9600, timeout=1)
print("connected to: " + ser.portstr)
except serial.SerialException:
pass
while True:
# Read a line and convert it from b'xxx\r\n' to xxx
line = ser.readline().decode('utf-8')[:-1]
if line: # If it isn't a blank line
# f=open('testing.txt','w+')
print(line)
#print >> f.write('test.txt')
f.close()
#print(line)
#with open('test.csv', 'w') as csv_file:
# writer = csv.DictWriter(csv_file, fieldnames=['header1'], lineterminator='\n')
ser.close()

import sys
sys.stdout = open('file', 'w')
print 'test'
or redirect the shell-output
$ python foo.py > file
Duplicate of this:
Redirect stdout to a file in Python?

Related

Python script - add file read as alternative option

I have the following code:
#!/usr/bin/env python
# coding=utf-8
import threading
import requests
import Queue
import sys
import re
#ip to num
def ip2num(ip):
ip = [int(x) for x in ip.split('.')]
return ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3]
#num to ip
def num2ip(num):
return '%s.%s.%s.%s' % ((num & 0xff000000) >> 24,(num & 0x00ff0000) >> 16,(num & 0x0000ff00) >> 8,num & 0x000000ff)
def ip_range(start, end):
return [num2ip(num) for num in range(ip2num(start), ip2num(end) + 1) if num & 0xff]
def bThread(iplist):
threadl = []
queue = Queue.Queue()
for host in iplist:
queue.put(host)
for x in xrange(0, int(SETTHREAD)):
threadl.append(tThread(queue))
for t in threadl:
t.start()
for t in threadl:
t.join()
#create thread
class tThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while not self.queue.empty():
host = self.queue.get()
try:
checkServer(host)
except:
continue
def checkServer(host):
ports = [80]
for k in ports:
try:
aimurl = "http://"+host+":"+str(k)
response = requests.get(url=aimurl,timeout=3)
serverText = response.headers['server']
if (response.status_code) == 403:
print "-"*50+"\n"+aimurl +" Server: "+serverText
except:
pass
if __name__ == '__main__':
print '\n############# CDN IP #############'
print ' '
print '################################################\n'
global SETTHREAD
try:
SETTHREAD = sys.argv[2]
iplist = []
file = open(sys.argv[1], 'r')
tmpIpList = file.readlines()
for ip in tmpIpList:
iplist.append(ip.rstrip("\n"))
print '\nEscaneando '+str(len(iplist))+" IP's...\n"
bThread(iplist)
except KeyboardInterrupt:
print 'Keyboard Interrupt!'
sys.exit()
This script works as follows, a range of ip is entered:
python2 script.py 104.0.0.0-104.0.1.255 100 (100 is the number of threads)
I want to add support so that it reads the ip of a file, and that the range also works.
python2 script.py ips.txt 100
I tried this:
file = open(sys.argv[1], 'r')
iplist = file.readlines()
But it does not work.
Edit1: added file reading code recommended by user Syed Hasan, the problem seems to be the bThread(iplist) function
I assume you're attempting to use 'iplist' the same way as your CLI input was attempting to parse it. However, the readlines function simply reads the entire file at once and appends a newline (\n) at the end (provided you do format the IPs with a succeeding newline character).
Currently, you should be getting a list of IPs with a succeeding newline character. Try removing it from the rightmost end using rstrip:
file = open(sys.argv[1], 'r')
tmpIpList = file.readlines()
for ip in tmpIpList:
iplist.append(ip.rstrip("\n"))
How you switch between the two modes is a challenge you should attempt to solve. Perhaps use command-line parameter support to identify the mode of operations (look into the argparse library).

Reading and appending to the same text file

I have a program that writes serial data to the text file. I want to check for specific card UIDs in the text file by reading the file at first, if there is already a card UID I want to skip the serial write step (serial write 0), if there isn't that card UID I will go ahead and serial write 1.
In order to check for card UIDs I have employed next command, please have a look at my code.
import threading
import serial
import sys
import io
import codecs
import queue
from pynput import keyboard
with io.open("uid.txt", "w", encoding="utf-8") as b:
b.write("")
q = queue.Queue()
ser = serial.Serial('COM4', baudrate = 9600, timeout = 5)
class SerialReaderThread(threading.Thread):
def run(self):
while True:
output = ser.readline().decode('utf-8')
print(output)
q.put(output)
class FileWriting(threading.Thread):
def run(self):
while True:
output = q.get()
with io.open("uid.txt", "r+", encoding="utf-8") as input:
for line in input:
if line.startswith("Card UID: "):
s = (next(input))
if line.startswith(s): ***
ser.write(b'0\r\n')
else:
ser.write(b'1\r\n')
with io.open("uid.txt", "a+", encoding="utf-8") as f:
f.write(output)
serial_thread = SerialReaderThread()
file_thread=FileWriting()
serial_thread.start()
file_thread.start()
serial_thread.join()
file_thread.join()
FileWriting thread is what I need help with. Again I want to first read the text file (which initially will be empty as it is created) and check for lines with card UID and look if there already is that specific card UID in the file if there is write 0 if there isn't write 1 in serial.
However running this code gives me an error:
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\project\fff.py", line 36, in run
s = (next(input))
StopIteration
Since you re-create the uid.txt file empty each time you run your program, you don't need a file to hold the information. Just use a set instead:
ser = serial.Serial('COM4', baudrate = 9600, timeout = 5)
class SerialReaderThread(threading.Thread):
def run(self):
uids = set()
while True:
output = ser.readline().decode('utf-8')
print(output)
response = b'0' if output in uids else b'1'
ser.write(response + b'\r\n')
uids.add(output)
serial_thread = SerialReaderThread()
serial_thread.start()
serial_thread.join()

how to export serial data collected using PySerial to csv file?

I'm trying to collect serial data from a device, timestamp and export it to a .csv file.
The following program writes date and time to csv but not the data returned from the device module:
import time
import csv
import fio2
def Csv_creator():
my_file = open('test_csv.csv', 'w+')
with my_file:
new_file = csv.writer(my_file)
def Timestamp():
date_now = time.strftime('%d/%m/%y')
time_now = time.strftime('%H:%M:%S')
return [date_now,time_now]
def Write_loop():
Csv_creator()
fio2.Initialize()
with open('test_csv.csv', 'a') as f:
csv_file = csv.writer(f)
for num in range(0,20):
[date_now,time_now] = Timestamp()
fio2_data = fio2.Reader()
print(fio2_data)
csv_file.writerow([date_now,time_now,fio2_data])
Write_loop()
The device module is as shown below. It returns the data and I'm able to print it. The only problem is not being able to write it on to the csv file.
import serial
ser = serial.Serial("COM4",
baudrate=2400,
bytesize=serial.EIGHTBITS,
parity =serial.PARITY_ODD)
def Initialize():
global ser
try:
ser.isOpen()
print("\n Serial is open")
except:
print ("Error: serial Not Open")
def Reader():
global ser
if (ser.isOpen()):
try:
x = ser.readline().decode()
x = (x)
return x
except:
return "unable to print"
else:
return "cannot open serial port"
I figured it out. I had to remove some garbage letters that were associated with the decimal values. First, I change the received data to string and replaced the garbage letters. Here's how I changed it:
[date_now,time_now] = Timestamp()
fio2_data = str(fio2.Reader()).replace("\r\n","")
fio2_data = fio2_data.replace("\x000","")
write_list = [date_now,time_now,fio2_data]

Python script won't run using path to file

If I run "python /home/pi/temp/getTemp.py" from the terminal command line I get
"Error, serial port '' does not exist!" If I cd to the temp directory and run "python getTemp.py" it runs fine. Can anyone tell me why?
#!/usr/bin/env python
import os
import sys
import socket
import datetime
import subprocess
import signal
port = "/dev/ttyUSB0"
tlog = '-o%R,%.4C'
hlog = '-HID:%R,H:%h'
clog = '-OSensor %s C: %.2C'
def logStuff(data):
with open("/home/pi/temp/templog.txt", "a") as log_file:
log_file.write(data + '\n')
def main():
try:
output = subprocess.check_output(['/usr/bin/digitemp_DS9097U', '-q', '-a'])
for line in output.split('\n'):
if len(line) == 0:
logStuff("len line is 0")
continue
if 'Error' in line:
logStuff("error in output")
sys.exit()
line = line.replace('"','')
if line.count(',') == 1:
(romid, temp) = line.split(',')
poll = datetime.datetime.now().strftime("%I:%M:%S %p on %d-%B-%y")
content =(romid + "," + poll + "," + temp)
print content
return content
except subprocess.CalledProcessError, e:
print "digitemp error:\n", e.output
except Exception as e:
logStuff('main() error: %s' %e)
os.kill(os.getpid(), signal.SIGKILL)
if __name__ == "__main__":
main()
It probably cannot find the configuration file, which is normally stored in ~/.digitemprc when you run it with -i to initialize the network. If it was created in a different directory you need to always tell digitemp where to find it by passing -c

file transfer code python

I found the code here: Send a file through sockets in Python (the selected answer)
But I will jut post it here again..
server.py
import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10)
while True:
sc, address = s.accept()
print address
i=1
f = open('file_'+ str(i)+".txt",'wb') #open in binary
i=i+1
while (True):
l = sc.recv(1024)
while (l):
print l #<--- i can see the data here
f.write(l) #<--- here is the issue.. the file is blank
l = sc.recv(1024)
f.close()
sc.close()
s.close()
client.py
import socket
import sys
s = socket.socket()
s.connect(("localhost",9999))
f=open ("test.txt", "rb")
l = f.read(1024)
while (l):
print l
s.send(l)
l = f.read(1024)
s.close()
On server code, the print l line prints the file contents..so that means that content is being transferred..
but then the file is empty??
what am i missing?
thanks
You are probably trying to inspect the file while the program is running. The file is being buffered, so you likely won't see any output in it until the f.close() line is executed, or until a large amount of data is written. Add a call to f.flush() after the f.write(l) line to see output in real time. Note that it will hurt performance somewhat.
Well that server code didn't work anyway, I've modified it to get it working.
The file was empty because it was stuck in the while True and never got around to closing the file.
Also i=1 was inside the loop so it was always writing to the same file.
import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10)
i=1
while True:
print "WILL accept"
sc, address = s.accept()
print "DID accept"
print address
f = open('file_'+ str(i)+".txt",'wb') #open in binary
i += 1
l = sc.recv(1024)
while (l):
f.write(l) #<--- here is the issue.. the file is blank
l = sc.recv(1024)
f.close()
sc.close()
print "Server DONE"
s.close()

Categories