I am using the following script as the basis for a homebuilt energy monitoring system. The script serves as a gateway between an arduino based receiver connected to the serial port and passes it on through MQTT as well as a http POST. The script is intended to run indefinitely. However it crashes at random intervals, anywhere from an hour to a week. I cannot figure out why. Any pointers on how to determine why and how to log the error would be appreciated. Here is the script:
import time
import datetime
import requests
import paho.mqtt.publish as publish
#import csv
import logging
logging.basicConfig(level=logging.ERROR, filename='serial-read.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')
device = '/dev/ttyUSB0' #this will have to be changed to the serial port you are using
data = ""
pieces = ""
while True:
while True:
try:
receiver = serial.Serial(device, 57600)
receiver.flushInput()
except serial.SerialException:
print "cannot connect. will try again..."
time.sleep(10)
else:
break
try:
data = receiver.readline()
#print (data)
#print repr(data)
#with open ("data_log.csv","a") as f:
#writer = csv.writer(f,delimiter=",")
#writer.writerow([time.time(),data])
pieces = data.split(" ")
try:
nodeid = int(pieces[0])
except ValueError:
pass
try:
data1 = int(pieces[1])
data2 = int(pieces[2])
data3 = int(pieces[3])
data4 = int(pieces[4])
except IndexError:
pass
#print nodeid
if nodeid == 6:
#print "Power:"
Irms = data3 + data4
print Irms
localtime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
localtime = "'" + localtime + "'"
#print localtime
payload = {"timestamp" : localtime, "Irms" : Irms}
r = requests.post('http://www.********.ca/*****.php', params=payload)
#print(r.url)
publish.single("myHome/energy/power", Irms, hostname="192.168.1.120")
elif nodeid == 2:
temp = float(data1)/10
#print "temp:"
#print temp
hum = data3
publish.single("myHome/garage/temperature", temp, hostname="192.168.1.120")
publish.single("myHome/garage/humidity", hum, hostname="192.168.1.120")
temphum = str(temp) + " " + str(hum)
publish.single("myHome/garage/temphum", temphum, hostname="192.168.1.120")
#print temphum
except serial.serialutil.SerialException:
print "no device connected. Please reconnect device..."
receiver.close()
time.sleep(5)
Thank you!
Baobab
Your second try statement catches the following exception:
except serial.serialutil.SerialException:
But what if the block of code generates a different exception? The script will exit. Add a second except, as in the first try loop, to catch any other exceptions, and print them to your log.
Related
Im currently writing a programm which scans the internet for port:25565. When it finds a open port a function as dramatiq acotr is called which check the adress(ip + port) for deatails. But dramatiq uses more than the function.
import json
import masscan
import socket
import dramatiq
import redis
import random
import pymongo
from colorama import Fore,init
init()
red = Fore.RED
white = Fore.WHITE
r = redis.Redis()
queue = "mc_check_queue"
client = pymongo.MongoClient("192.168.188.32:27017")
if client.server_info():
print("Connected to MongoDB successfully!")
else:
print("Could not connect to MongoDB.")
db = client["treffer"]
collection = db["ips"]
#dramatiq.actor
def mc_and_check_task(ip):
ip = JavaServer.lookup(ip)
try:
status = ip.status()
print(status)
mc_status = {"ip": ip, "status": status}
collection.insert_one(mc_status)
except socket.timeout:
return "Fehler socket.timeout"
except BrokenPipeError:
return "Fehler BrokenPipeError"
except Exception as e:
return f"An error occurred: + {e}"
A = list(range(1,255))
B = list(range(1,255))
random.shuffle(A)
random.shuffle(B)
ip_ranges = []
for a in A:
for b in B:
ip_range = f"{a}.{b}.0.0/16"
ip_ranges.append(ip_range)
for ip_range in ip_ranges:
print(ip_range)
try:
mas = masscan.PortScanner()
mas.scan(ip_range, ports="25565", arguments="--max-rate 1000000")
x = json.loads(mas.scan_result)
len_result = len(x["scan"])
if len_result > 0:
print(f"Results: {red}{len_result}")
else:
print(f"Results: {white}{len_result}")
for ip in x["scan"]:
adresse = ip + ":" + "25565"
mc_and_check_task.send(adresse)
for document in db.collection.find():
print(document)
except masscan.NetworkConnectionError:
print(f"{ip_range}masscan connection error")
print("done scanning")
The dramatiq terminal output looks like this:
165.227.0.0/16
Results:
0
done scanning
81.222.0.0/16
Results:
0
done scanning
243.155.0.0/16
Results:
0
done scanning
The output of the main terminal looks identical except that in the main window it takes like 10 sec for a new ip range to get printed due to scanning. The dramatiq windows on the other hand just prints out random ip ranges. Why does the decorator include more than just the function. What I want is that the status of the adress is printed in the dramatiq window and the ip range + results + done scanning in the main window.
Thanks.
I am trying to send textual commands to a microcontroller through usb serial port (ttyUSB0), the controller should respond with 'Y' or 'N' and execute the command. Commands are given in the following form '#01a' where the # is beginning symbol 0 is position for A channel and 1 position for B channel and 'a' is checksum of A+B.
I'm stuck and a beginner in python so any help is welcome and appreciated.
p.s. when I connect using putty everything works as expected
also the OS is Ubuntu 16.04 LTS
This is my code:
import time
import serial
import binascii
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=19200,
)
print 'Enter your commands below.\r\nInsert "exit" to leave the application.'
AT = chr(int('1000000',2))
A = chr(int('100000',2))
B = chr(int('100000',2))
AB = chr(int('1000000',2))
input = AT + A + B + AB
print input
try:
ser.open()
except Exception, e:
print "error open serial port: " + str(e)
exit()
if ser.isOpen():
try:
ser.flushInput() #flush input buffer, discarding all its contents
ser.flushOutput()#flush output buffer, aborting current output
#and discard all that is in buffer
#write data
ser.write(input)
# print("write data: AT+CSQ")
time.sleep(0.5) #give the serial port sometime to receive the data
numOfLines = 0
while True:
response = ser.readline()
print("read data: " + response)
numOfLines = numOfLines + 1
if (numOfLines >= 5):
ser.close()
except Exception, e1:
print "error communicating...: " + str(e1)
else:
print "cannot open serial port "
Hello I have trouble with read/write from or to device. I wanted to make a serial connection via rs 485 (half-duplex) . When I call read and write functions they didnt receive a data. Anyone know what I do wrong?
def Transmission(ser,data):
if ser.isOpen():
try:
print(data)
ser.flushInput()
ser.flushOutput()
ser.rtscts = True
ser.write(data)
time.sleep(0.1)
numOfLines = 0
print("write: " + data)
while True:
response = ser.readline()
print("read data: " + response)
ser.rtscts = False
numOfLines = numOfLines + 1
if(numOfLines >= 5):
ser.close()
except Exception, e1:
print "error communicating...: " + str(e1)
else:
print "cannot open serial port "
return response
Terminal didnt show receiving data:
powah
write: powah
read data:
read data:
read data:
read data:
read data:
I tried to write with read in the loop (with changing ser.rtscts). How to fix that problem? Thank You
I've been editing this port scanner for an information security project.
The code works but throws errors (Pycharm Edu) on lines 63 and 34 in that order.
The error message for line 63 is: 'line 63, in
checkhost(target). I've looked at this and can't see why this would throw an error specifically as it is defined on line 34.
The error message for line 34 is: 'NameError: global name 'conf' is not defined'. It's not clear why this is a problem either.
Any help is much appreciated.
The Python code environment is Python 2.7.10
#! /usr/bin/python
from logging import getLogger, ERROR # Import Logging Things
getLogger("scapy.runtime").setLevel(ERROR) # Get Rid if IPv6 Warning
import scapy
import sys
from datetime import datetime # Other stuff
from time import strftime
try:
target = raw_input("[*] Enter Target IP Address: ")
min_port = raw_input("[*] Enter Minumum Port Number: ")
max_port = raw_input("[*] Enter Maximum Port Number: ")
try:
if int(min_port) >= 0 and int(max_port) >= 0 and
int(max_port) >= int(min_port): # Test for valid range of ports
pass
else: # If range didn't raise error, but didn't meet criteria
print "\n[!] Invalid Range of Ports"
print "[!] Exiting..."
sys.exit(1)
except Exception: # If input range raises an error
print "\n[!] Invalid Range of Ports"
print "[!] Exiting..."
sys.exit(1)
except KeyboardInterrupt: # In case the user wants to quit
print "\n[*] User Requested Shutdown..."
print "[*] Exiting..."
sys.exit(1)
ports = range(int(min_port), int(max_port)+1)
start_clock = datetime.now() # Start clock for scan time
SYNACK = 0x12 # Set flag values for later reference
RSTACK = 0x14
def checkhost(target): # Function to check if target is up
conf.verb = 0 # Hide output
try:
ping = sr1(IP(dst = ip)/ICMP()) # Ping the target
print "\n[*] Target is Up, Beginning Scan..."
except Exception: # If ping fails
print "\n[!] Couldn't Resolve Target"
print "[!] Exiting..."
sys.exit(1)
def scanport(port): # Function to scan a given port
try:
srcport = RandShort() # Generate Port Number
conf.verb = 0 # Hide output
SYNACKpkt = sr1(IP(dst = target)/TCP(sport = srcport,
dport = port,flags = "S"))
pktflags = SYNACKpkt.getlayer(TCP).flags
if pktflags == SYNACK: # Cross reference Flags
return True # If open, return true
else:
return False
RSTpkt = IP(dst = target)/TCP(sport = srcport, dport = port,
flags = "R") # Construct RST packet send(RSTpkt)
except KeyboardInterrupt: # In case the user needs to quit
RSTpkt = IP(dst = target)/TCP(sport = srcport, dport = port,
flags = "R") send(RSTpkt)
print "\n[*] User Requested Shutdown..."
print "[*] Exiting..."
sys.exit(1)
checkhost(ip) # Run checkhost() function from earlier
print "[*] Scanning Started at " + strftime("%H:%M:%S") + "!\n"
for port in ports: # Iterate through range of ports
status = scanport(port) # Feed each port into scanning function
if status == True: # Test result
print "Port " + str(port) + ": Open" # Print status
stop_clock = datetime.now() # Stop clock for scan time
total_time = stop_clock - start_clock # Calculate scan time
print "\n[*] Scanning Finished!" # Confirm scan stop
print "[*] Total Scan Duration: " + str(total_time) # Print scan time
The problem is with your import statement, it should
be:
>>> import scapy
>>> from scapy.all import conf
>>> conf.verb = 0
or even better to get rid of possible similar errors in the future
just import scapy as:
>>> from scapy.all import *
>>> conf.verb = 0
Now it should work fine.
Reading data from the serial port:
readline() in the below code return the null vector, the reading data from the serial port is hexadecimal number like AABB00EF the putty gives me the output means the communication is working but nothing works via python
here is the code:
#!/usr/bin/python
import serial, time
ser = serial.Serial()
ser.port = "/dev/ttyUSB0"
ser.baudrate = 115200
#ser.bytesize = serial.EIGHTBITS
#ser.parity = serial.PARITY_NONE
#ser.stopbits = serial.STOPBITS_ONE
#ser.timeout = None
ser.timeout = 1
#ser.xonxoff = False
#ser.rtscts = False
#ser.dsrdtr = False
#ser.writeTimeout = 2
try:
ser.open()
except Exception, e:
print "error open serial port: " + str(e)
exit()
if ser.isOpen():
try:
#ser.flushInput()
#ser.flushOutput()
#time.sleep(0.5)
# numOfLines = 0
# f=open('signature.txt','w+')
while True:
response = ser.readline()
print len(response)
#f=ser.write(response)
print response
# numOfLines = numOfLines + 1
f.close()
ser.close()
except Exception, e1:
print "error communicating...: " + str(e1)
else:
print "cannot open serial port "
readline will try to read until the end of the line is reached, if there is no \r or \n then it will wait forever (if you have a timeout it might work...) instead try something like this
ser.setTimeout(1)
result = ser.read(1000) # read 1000 characters or until our timeout occures, whichever comes first
print repr(result)
just use this code
ser = serial.Serial("/dev/ttyUSB0",115200,timeout=1)
print "OK OPENED SERIAL:",ser
time.sleep(1)# if this is arduino ... wait longer time.sleep(5)
ser.write("\r") # send newline
time.sleep(0.1)
print "READ:",repr(ser.read(8))
you can create a readuntil method
def read_until(ser,terminator="\n"):
resp = ""
while not resp.endswith(terminator):
tmp = ser.read(1)
if not tmp: return resp # timeout occured
resp += tmp
return resp
then just use it like
read_until(ser,"\r")