正常工作数小时后的突然错误:调用Python对象时,递归错误超过了最大递归深度



我使用arduino通过串行将数据馈送到raspi4,然后通过googleapi将数据上传到google表单。

一段时间以来,情况一直很好,但现在由于某种未知的原因,伐木在半夜停止了。当我查看pycharm命令行时,我看到了一大堆命令(我没有全部复制,只是复制了最后一个屏幕(:

File "/home/pi/Downloads/WATER PROJECT/MAIN/lib/python3.7/site-packages/requests/sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "/home/pi/Downloads/WATER PROJECT/MAIN/lib/python3.7/site-packages/requests/adapters.py", line 449, in send
timeout=timeout
File "/home/pi/Downloads/WATER PROJECT/MAIN/lib/python3.7/site-packages/urllib3/connectionpool.py", line 672, in urlopen
chunked=chunked,
File "/home/pi/Downloads/WATER PROJECT/MAIN/lib/python3.7/site-packages/urllib3/connectionpool.py", line 421, in _make_request
six.raise_from(e, None)
File "<string>", line 3, in raise_from
File "/home/pi/Downloads/WATER PROJECT/MAIN/lib/python3.7/site-packages/urllib3/connectionpool.py", line 416, in _make_request
httplib_response = conn.getresponse()
File "/usr/lib/python3.7/http/client.py", line 1321, in getresponse
response.begin()
File "/usr/lib/python3.7/http/client.py", line 320, in begin
self.headers = self.msg = parse_headers(self.fp)
File "/usr/lib/python3.7/http/client.py", line 214, in parse_headers
return email.parser.Parser(_class=_class).parsestr(hstring)
File "/usr/lib/python3.7/email/parser.py", line 68, in parsestr
return self.parse(StringIO(text), headersonly=headersonly)
File "/usr/lib/python3.7/email/parser.py", line 57, in parse
feedparser.feed(data)
File "/usr/lib/python3.7/email/feedparser.py", line 176, in feed
self._call_parse()
File "/usr/lib/python3.7/email/feedparser.py", line 180, in _call_parse
self._parse()
File "/usr/lib/python3.7/email/feedparser.py", line 256, in _parsegen
if self._cur.get_content_type() == 'message/delivery-status':
File "/usr/lib/python3.7/email/message.py", line 578, in get_content_type
value = self.get('content-type', missing)
File "/usr/lib/python3.7/email/message.py", line 471, in get
return self.policy.header_fetch_parse(k, v)
File "/usr/lib/python3.7/email/_policybase.py", line 316, in header_fetch_parse
return self._sanitize_header(name, value)
File "/usr/lib/python3.7/email/_policybase.py", line 287, in _sanitize_header
if _has_surrogates(value):
File "/usr/lib/python3.7/email/utils.py", line 57, in _has_surrogates
s.encode()
RecursionError: maximum recursion depth exceeded while calling a Python object
Process finished with exit code 1

我使用的代码:

import logging
import random
import time
import serial
import os
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from datetime import datetime

def init_connection(ser, last_experiment=None):
"""
This function is used to initialize the connection with google's system.
:param ser: The reference to the serial object we use to communicate with the ATMega328P
:param last_experiment: If none - it is a normal experiment but else can be used to continue a running experiment
:return:
"""
# Use credentials to create a client to interact with the Google Drive API
scope = ['https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(creds)
# Make sure you use the right name here
spread_sheet = client.open("EXPERIMENTS")
init_experiment(ser, spread_sheet, last_experiment=last_experiment)

def init_experiment(ser, spread_sheet, last_experiment=None):
"""
This function is used to initialize the experiment: create a new worksheet for the experiment and set it up.
:param ser: The reference to the serial object we use to communicate with the ATMega328P
:param spread_sheet: The spreadsheet of the experiment.
:param last_experiment: If none - it is a normal experiment but else can be used to continue a running experiment
:return:
"""
experiment_time = datetime.now().strftime("%Y%m%d%H%M%S")
print(spread_sheet.title + "@" + experiment_time)
logging.log(100, spread_sheet.title + "@" + experiment_time)
# create new worksheet
if last_experiment is None:
worksheet = spread_sheet.add_worksheet(title="experiment@" + experiment_time, rows=10000, cols=15)
else:
worksheet = spread_sheet.worksheet(last_experiment[0])
# add titles
worksheet.update_acell('A1', 't')
worksheet.update_acell('B1', 'T_1')
worksheet.update_acell('C1', 'T_2')
worksheet.update_acell('D1', 'T_3')
worksheet.update_acell('E1', 'T_4')
worksheet.update_acell('F1', 'T_5')
worksheet.update_acell('G1', 'T_6')
worksheet.update_acell('H1', 'RH_1')
worksheet.update_acell('I1', 'RH_2')
worksheet.update_acell('J1', 'RH_3')
worksheet.update_acell('K1', 'RH_4')
worksheet.update_acell('L1', 'RH_5')
worksheet.update_acell('M1', 'RH_6')
worksheet.update_acell('N1', 'FLOW')
worksheet.update_acell('O1', 'WEIGHT')
print("t, T_1, T_2, T_3, T_4, T_5, T_6, RH_1, RH_2, RH_3, RH_4, RH_5, RH_6, FLOW, WEIGHT")
logging.log(100, "t, T_1, T_2, T_3, T_4, T_5, T_6, RH_1, RH_2, RH_3, RH_4, RH_5, RH_6, FLOW, WEIGHT")
# start experiment loop
if last_experiment is None:
start_experiment(ser, worksheet=worksheet)
else:
start_experiment(ser, worksheet=worksheet, worksheet_row=last_experiment[1])

def start_experiment(ser, worksheet, worksheet_row=2):
"""
The experiment loop, measure the sensors and update the sheet.
:param ser: The reference to the serial object we use to communicate with the ATMega328P
:param worksheet: The specific sheet we edit
:param worksheet_row: The row we're writing at
:return:
"""
print(worksheet_row)
while True:
try:
# get measurements and cell range:
measurements = get_measurements(ser)
print("vals=" + str(measurements))
logging.log(100, "vals=" + str(measurements))
cell_list = worksheet.range('A' + str(worksheet_row) + ':O' + str(worksheet_row))
# update in sheets
for i in range(len(measurements)):
cell_list[i].value = measurements[i]
worksheet.update_cells(cell_list, 'USER_ENTERED')
except Exception as e:
print(e)
logging.log(100, e)
time.sleep(100)
init_connection(ser, last_experiment=(worksheet.title, worksheet_row))
# next row and wait for some time
worksheet_row += 1
time.sleep(30)

def get_measurements(ser):
"""
This function measures the sensors of the experiment
:param ser: The reference to the serial object we use to communicate with the ATMega328P
:return: Array of the measurement according to this order: t, T_in, T_out, T_aux, RH_in, RH_out,         RH_aux, Flux,WaterLevel
"""
t = datetime.now().strftime('%d/%m/%Y %H:%M:%S')
# Here we read the data from the sensors
T_1 = random.randint(1, 3)
T_2 = random.randint(1, 10) + 15
T_3 = random.randint(1, 3) - 5
T_4 = random.randint(1, 4)
T_5 = random.randint(1, 10) + 13
T_6 = random.randint(1, 3) - 7
RH_1 = random.randint(1, 5) + 55
RH_2 = random.randint(1, 5) + 40
RH_3 = random.randint(1, 5) + 50
RH_4 = random.randint(1, 5) + 53
RH_5 = random.randint(1, 5) + 42
RH_6 = random.randint(1, 5) + 51
FLOW = random.randint(1, 100) + 400
WEIGHT = random.randint(1, 100) + 5
data = [ser.read()]
if data[0] != b'':
newByte = ser.read()
while newByte != b'':
data.append(newByte)
newByte = ser.read()
data = b''.join(data)
data = data.decode("utf-8")
print('data_read=' + str(data))
data = data.split('n')
list_of_parameters = ['t=', 'T1=', 'RH1=', 'T2=', 'RH2=', 'T3=', 'RH3=', 'T4=', 'RH4=', 'T5=', 'RH5=', 'T6=', 'RH6=', 'FLOW=', 'WEIGHT='] #need to be exactly the same as written in the arduino serial monitor
for line in data:
if any(x not in line for x in list_of_parameters):
data.remove(line)
data = data[len(data) - 1]        
print('data=' + str(data))
data = data.split(' ')
uptime= (data[0])[data[0].index('=') + 1:]
T_1= (data[1])[data[1].index('=') + 1:]
RH_1 = (data[2])[data[2].index('=') + 1:]
T_2 = (data[3])[data[3].index('=') + 1:]
RH_2 = (data[4])[data[4].index('=') + 1:]
T_3 = (data[5])[data[5].index('=') + 1:]
RH_3 = (data[6])[data[6].index('=') + 1:]
T_4 = (data[7])[data[7].index('=') + 1:]
RH_4 = (data[8])[data[8].index('=') + 1:]
T_5 = (data[9])[data[9].index('=') + 1:]
RH_5 = (data[10])[data[10].index('=') + 1:]
T_6 = (data[11])[data[11].index('=') + 1:]
RH_6 = (data[12])[data[12].index('=') + 1:]
FLOW = (data[13])[data[13].index('=') + 1:]
WEIGHT = (data[14])[data[14].index('=') + 1:]
return t, T_1, T_2, T_3,T_4, T_5, T_6, RH_1, RH_2, RH_3, RH_4, RH_5, RH_6,FLOW,WEIGHT

if __name__ == '__main__':
logging.basicConfig(filename='logs/experiment@' + datetime.now().strftime("%Y%m%d%H%M%S") +'.log', filemode='w',
level=100, format="")
print('Initializing program')
logging.log(100, 'Initializing program')
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=0.1)
time.sleep(1)
print('Serial connection is okay')
logging.log(100, 'Serial connection is okay')
init_connection(ser)

我怀疑错误的来源是互联网问题,但话说回来,大楼里的互联网运行得很好。现在它也运行良好。有人经历过这种情况吗?或者可以告诉我如何解决这种问题吗?

谢谢!

在我看来,这就像是您的互联网连接或内部模块出现问题。异常中没有任何内容专门引用您的代码。如果不深入研究,我敢打赌,你的互联网一夜之间瘫痪了一段时间,你用来连接到谷歌API的模块正在递归地尝试重新连接。只是我的预感。

最新更新