Sending ^C over PySerial - python

I'm writing an automated script to reset the password on a Cisco 1800 series router. In order to begin the reset process, you must enter the ROMMON by sending a break when the ROMMON is initialized. For the life of me, I cannot send a break over PySerial, no matter how hard I try. Here is the code I've been using:
import serial, time
effinByte = '\x03'
ser = serial.Serial('/dev/ttyS0', 9600, timeout=1.0, rtscts=False)
if(ser.isOpen() == False):
ser.open()
print("Opening port")
else:
print("Port already open")
isNotResetting = True
while isNotResetting == True:
print("Waiting for ROMMON")
theOutput = ser.readline()
if ("ROMMON" in theOutput):
ser.write(effingByte.encode('ascii'))
print ('Mr. Meeseeks find!')
while True:
print ser.readline()
Basically, it waits for the 'initializing ROMMON' line and tries to send a break.

sendBreak(self) is the answer. I'm so stupid!

Related

Chat server - can't receive message while getting input from user

Okay so I understood what I did wrong. But I have another problem now, where using multithreading doesn't work as intended. In the code below, in the main fucntion, I start the message_listener thread, which should work in the background while I get user input. But when I send something from another client, the message doesn't get printed (and it should) in the other client's terminal. Not even after the receiver client send a message himself. I dont understand what I got wrong.
import socket
import sys
import threading
from datetime import datetime
import errno
import msvcrt
HEADER_LENGTH = 10
HOST = "127.0.0.1" # Standard loopback interface address (localhost)
PORT = 50000 # Port to listen on (non-privileged ports are > 1023)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", PORT))
client.setblocking(False)
username = input("Choose a username: ")
username_header = f"{len(username.encode()):<{HEADER_LENGTH}}".encode()
client.send(username_header + username.encode())
def client_input(u_name):
print(f"{u_name}>", end="")
msg = ""
done = False
while not done:
if msvcrt.kbhit():
pressed = msvcrt.getch()
if pressed == b"\r":
print("")
done = True
else:
print(pressed.decode(), end="")
msg += pressed.decode()
return msg
def message_handler():
while True:
try:
uname_header = client.recv(HEADER_LENGTH)
if not len(uname_header):
print('Connection closed by the server')
sys.exit()
# actual username
sender_username_length = int(uname_header.decode().strip())
sender_username = client.recv(sender_username_length).decode()
sender_message_header = client.recv(HEADER_LENGTH)
sender_message_length = int(sender_message_header.decode().strip())
sender_msg = client.recv(sender_message_length).decode()
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
print(f"<{current_time}> {sender_username}: {sender_msg}")
except IOError as error:
if error.errno != errno.EAGAIN and error.errno != errno.EWOULDBLOCK:
print(f"There was some error reading data: {str(error)}")
sys.exit()
# no data was received (everything's fine)
return
except Exception as error:
print(f"There was some error reading data: {str(error)}")
sys.exit()
def main():
msg_listener = threading.Thread(target=message_handler)
msg_listener.start()
while True:
message = client_input(username)
# if message is not empty, send it.
if message:
# Encode message to bytes, prepare header and convert to bytes, like for username above, then send
message = message.encode()
message_header = f"{len(message):<{HEADER_LENGTH}}".encode()
client.send(message_header + message)
if __name__ == "__main__":
main()
It seems like the message_handler doesn't receive anything... Because if for example, I put a print statement after the uname_header = client.recv(HEADER_LENGTH) line , it doesn't get printed. So it means the thread isn't working in the background? i dont get it.
For some reason, after one iteration over the while True loop in the main function, the msg_listener thread stops. Why does it stop tho? it has a while True loop in it!
This is because the program waits for input from the user before receiving new messages. Your actions do not work in parallel.
I suggest making the following changes
import threading
def message_handler():
while True:
# open listening and print new msg
if __name__ == "__main__":
msg_listener = threading.Thread(target=message_handler)
msg_listener.start()
while True:
message = client_input(username)
# send msg
In this case, you will always listen to messages in the background. And in the main thread to process user input

Reconnecting with pySerial

I'm trying to write a function which continuously reads serial input. The function must be able to handle unexpected disconnections from the serial port and reconnect when possible. Despite reading several question posts on stackOverflow and looking through the pySerial documentation, I have yet to find a solution.
Here's my code:
def serialRead(serialPort, queue):
"""Adds serial port input to a queue."""
ser = serial.Serial(serialPort - 1, timeout = 2)
ser.parity = "O"
ser.bytesize = 7
while(True):
try:
if(ser == None):
ser = serial.Serial(serialPort - 1, timeout = 2)
ser.parity = "O"
ser.bytesize = 7
print("Reconnecting")
queue.put(ser.read(27))
ser.write(chr(6).encode())
print("Writing Data...")
except:
if(not(ser == None)):
ser.close()
ser = None
print("Disconnecting")
print("No Connection")
time.sleep(2)
Here's my output:
Enter a Serial Port: 7
Writing Data...
Writing Data...
Writing Data...
Writing Data...
I start with my device connected. After leaving the program run, neither "Disconnecting" or "No Connection" display and the program stops (it doesn't crash).
This code works. Batman tested the program on an Arduino connection and I found that my program had successfully reconnected with the device after a period of time. I hope this code will be useful for those struggling with something similar.

Python: Writing to and Reading from serial port

I've read the documentation, but can't seem to find a straight answer on this.
I have a list of all COM Ports in use by Modems connected to the computer. From this list, I try to open it, send it a command, and if it says anything back, add it to another list. I'm not entirely sure I'm using pyserial's read and write functions properly.
i=0
for modem in PortList:
for port in modem:
try:
ser = serial.Serial(port, 9600, timeout=1)
ser.close()
ser.open()
ser.write("ati")
time.sleep(3)
print ser.read(64)
if ser.read(64) is not '':
print port
except serial.SerialException:
continue
i+=1
I'm not getting anything out of ser.read(). I'm always getting blank strings.
a piece of code who work with python to read rs232
just in case somedoby else need it
ser = serial.Serial('/dev/tty.usbserial', 9600, timeout=0.5)
ser.write('*99C\r\n')
time.sleep(0.1)
ser.close()
ser.read(64) should be ser.read(size=64); ser.read uses keyword arguments, not positional.
Also, you're reading from the port twice; what you probably want to do is this:
i=0
for modem in PortList:
for port in modem:
try:
ser = serial.Serial(port, 9600, timeout=1)
ser.close()
ser.open()
ser.write("ati")
time.sleep(3)
read_val = ser.read(size=64)
print read_val
if read_val is not '':
print port
except serial.SerialException:
continue
i+=1

Have a function time out if a certain condition is not fulfilled in time

The issue I have is that my chat client is supposed to recieve and print data from server when the server sends it, and then allow the client to reply.
This works fine, except that the entire process stops when the client is prompted to reply. So messages pile up until you type something, and after you do that, then it prints all the recieved messages.
Not sure how to fix this, so I decided why not have the client's time to type a reply timeout after 5 seconds, so that the replies can come through regardless. It's pretty flawed, because the input will reset itself, but it works better anyways.
Here's the function that needs to have a timeout:
# now for outgoing data
def outgoing():
global out_buffer
while 1:
user_input=input("your message: ")+"\n"
if user_input:
out_buffer += [user_input.encode()]
# for i in wlist:
s.send(out_buffer[0])
out_buffer = []
How should I go about using a timeout? I was thinking of using time.sleep, but that just pauses the entire operation.
I tried looking for documentation. But I didn't find anything that would help me make the program count up to a set limit, then continue.
Any idea's about how to solve this? (Doesn't need to use a timeout, just needs to stop the message pileup before the clients reply can be sent) (Thanks to all who helped me get this far)
For Ionut Hulub:
from socket import *
import threading
import json
import select
import signal # for trying to create timeout
print("client")
HOST = input("connect to: ")
PORT = int(input("on port: "))
# create the socket
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
print("connected to:", HOST)
#--------- need 2 threads for handling incoming and outgoing messages--
# 1: create out_buffer:
out_buffer = []
# for incoming data
def incoming():
rlist,wlist,xlist = select.select([s], out_buffer, [])
while 1:
for i in rlist:
data = i.recv(1024)
if data:
print("\nreceived:", data.decode())
# now for outgoing data
def outgoing():
global out_buffer
while 1:
user_input=input("your message: ")+"\n"
if user_input:
out_buffer += [user_input.encode()]
# for i in wlist:
s.send(out_buffer[0])
out_buffer = []
thread_in = threading.Thread(target=incoming, args=())
thread_out = threading.Thread(target=outgoing, args=())
thread_in.start() # this causes the thread to run
thread_out.start()
thread_in.join() # this waits until the thread has completed
thread_out.join()
We can use signals for the same. I think the below example will be useful for you.
import signal
def timeout(signum, frame):
raise Exception
#this is an infinite loop, never ending under normal circumstances
def main():
print 'Starting Main ',
while 1:
print 'in main ',
#SIGALRM is only usable on a unix platform
signal.signal(signal.SIGALRM, timeout)
#change 5 to however many seconds you need
signal.alarm(5)
try:
main()
except:
print "whoops"

Problem opening serial port with Pyserial

I'm trying to read numerical values sent over a bluetooth modem from a serial port using Pyserial. I'm a beginner at Python, and found a good example that I'm trying to make use of.
from threading import Thread
import time
import serial
last_received = ''
def receiving(ser):
global last_received
buffer = ''
while True:
buffer = buffer + ser.read(ser.inWaiting())
if '\n' in buffer:
lines = buffer.split('\n') # Guaranteed to have at least 2 entries
last_received = lines[-2]
#If the modem sends lots of empty lines, you'll lose the
#last filled line, so you could make the above statement conditional
#like so: if lines[-2]: last_received = lines[-2]
buffer = lines[-1]
class SerialData(object):
def __init__(self, init=50):
try:
self.ser = ser = serial.Serial(
port='/dev/tty.FireFly-16CB-SPP',
baudrate=115200,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
except serial.serialutil.SerialException:
#no serial connection
self.ser = None
else:
Thread(target=receiving, args=(self.ser,)).start()
def next(self):
if not self.ser:
return 140 #return anything so we can test when Arduino isn't connected
#return a float value or try a few times until we get one
for i in range(40):
raw_line = last_received
try:
return float(raw_line.strip())
except ValueError:
print 'bogus data',raw_line
time.sleep(.005)
return 0.
def __del__(self):
if self.ser:
self.ser.close()
if __name__=='__main__':
s = SerialData()
for i in range(500):
time.sleep(.015)
print s.next()
I can open the port in another program, and can send/receive data from it. However, the code above doesn't seem to open the port, and just repeats "100" to the terminal window 500 times, but I don't know where it comes from or why the port doesn't open correctly. There isn't a delay from opening the port as it is on the other program, so I don't even know if it attempts to open.
I don't know what else to try, or where the error is so I'm asking for help. What am I doing wrong?
except serial.serialutil.SerialException:
You're catching and silencing errors in connecting. Comment out this block, and see if it produces an error message.

Categories