Python 3 urllib urlretrieve retry on download fail - python-3.x

I have a program that downloads files from a server. They are anywhere from 2mb to 8mb. It runs through a loop and grabs the number of files I request. The problem is that my internet sucks out here in the middle of the freekin' desert. While everything works beautifully most of the time, sometimes the internet drops during a urllib.request.urlretrieve request and freezes up the program. I need a way to get urllib to detect when the net has dropped, and retry the file until it comes back up again. Any help appreciated!!!
Example of what I am doing:
try:
numimgs = len(imgsToGet)
path1 = "LEVEL II" #HIGHTEST FOLDER
self.fn = imgs.split('/')[-1] #SPLIT OUT NAME FROM LEFT
path2 = self.fn[:4] #SPLIT OUT KICX
path3 = self.fn.split('_')[1] #SPLIT OUT DATE
savepath = os.path.join(path1, path2, path3) #LEVEL II / RADAR / DATE PATH
if not os.path.isdir(savepath): #See if it exists
os.makedirs(savepath) #If not, make it
fileSavePath = os.path.join(path1, path2, path3, self.fn)
if os.path.isfile(fileSavePath): #chcek to see if image path already exists
self.time['text'] = self.fn + ' exists \n'
continue
#DOWNLOAD PROGRESS
def reporthook(blocknum, blocksize, totalsize):
percent = 0
readsofar = blocknum * blocksize
if totalsize > 0:
percent = readsofar * 1e2 / totalsize
if percent >= 100:
percent = 100
s = "\r%5.1f%% %*d / %d" % (
percent, len(str(totalsize)), readsofar, totalsize)
self.time['text'] = 'Downloading File: '+str(curimg)+ ' of '+str(numimgs)+' '+self.fn+'' + s
if readsofar >= totalsize: # near the end
self.time['text'] = "Saving File..."
else: # total size is unknown
self.time['text'] = "read %d\n" % (readsofar)
#UPDATE PROGRESSBAR
self.pb.config(mode="determinate")
if percent > 0:
self.dl_p = round(percent,0)
self.pb['value'] = self.dl_p
self.pb.update()
if percent > 100:
self.pb['value'] = 0
self.pb.update()
urllib.request.urlretrieve(imgs, fileSavePath, reporthook)
except urllib.error.HTTPError as err: #catch 404 not found and continue
if err.code == 404:
self.time['text'] = ' Not Found'
continue
Cheers,
David

You could place the code in a try except block, with a counter. Here is what I had done:
remaining_download_tries = 15
while remaining_download_tries > 0 :
try:
urlretrieve(CaseLawURL,File_Path_and_Name)
print("successfully downloaded: " + CaseLawURL)
time.sleep(0.1)
except:
print("error downloading " + CaseLawURL +" on trial no: " + str(16 - remaining_download_tries))
remaining_download_tries = remaining_download_tries - 1
continue
else:
break
I hope the code is self explanatory. Regards

Related

Keep getting else/elif invalid syntax error

Currently I'm writing a code where I want to ask motor values from motor controller using raspberry pi. However my code is throwing InvalidSyntax Error in else and elif statements. I've already read about if and elif statements in python, but I can't figure out mistake by myself. The code is below:
def motor_values():
while 1:
command_1 = '?A '+str(1)+' \r' #Asking first motor current
command_2 = '?A '+str(2)+' \r' #Asking second motor current
counter = 0
#First motor current
if counter = 0:
ser.write(command_1.encode()) #string to bytes
data_1 = ser.readline().decode().strip() #bytes to string
#Checking if data is received and extracting current value
if 'A=' in data_1:
value_1 = int(data_1.split('=')[1])
print("Motor Current(Channel 1): " + str((value_1) + " Ampers")
counter += 1
else:
print("Message is not received")
#Second motor current
elif counter == 1:
ser.write(command_2.encode()) #string to bytes
data_2 = ser.readline().decode().strip() #bytes to string
if 'A=' in data_2:
value_2 = int(data_2.split('=')[1])
print("Motor Current(Channel 2): " + str((value_2) + " Ampers")
counter += 1
else:
print("Message is not received")
else:
counter = 0
A few syntax errors here:
use == in the if clause condition
#First motor current
if counter == 0: #
remove one of the two ( in str((value_2)
print("Motor Current(Channel 1): " + str(value_1) + " Ampers")
print("Motor Current(Channel 2): " + str(value_2) + " Ampers")
you missed closing brace in print function
print("Motor Current(Channel 1): " + str(value_1) + " Ampers")

TypeError: missing 1 required positional argument: 'value'

experts
I meet an value missing error in my code , but I think the variable in function are claimed. I don't know why it is happens.
$ python check_rsg_V0312.py
2018-03-20 13:05:49 === Script Start ===
2018-03-20 13:05:49 Monitoring via remote logon
The authenticity of host 'rpahost0 ([127.0.0.1]:7000)' can't be established.
RSA key fingerprint is 2d:f5:67:75:84:b6:24:45:e6:48:60:65:61:ca:69:f7.
Are you sure you want to continue connecting
(yes/no)? yes
Warning: Permanently added 'rpahost0' (RSA) to the list of known hosts.
Password:
Traceback (most recent call last):
File "check_rsg_V0312.py", line 89, in <module>
label = ssh_cmd(nLocalport, rsg_target, ouser, lookip, opasw, command,)
File "check_rsg_V0312.py", line 79, in ssh_cmd
print (ssh.before.decode(),ssh.after().decode())
TypeError: __init__() missing 1 required positional argument: 'value'
Below is my code, it is really strange that one error happens in ssh_cmd
function. detailed please review comments in code.
import os,time,pexpect,re, subprocess, smtplib
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
#-----------------------------------------
dir = os.environ['HOME']
ouser = 'x02d726'
opasw = 'qwe12'
nLocalport = 7000
lookip = '127.0.0.1'
rsg_target = "rpahost0"
command = "ls -ltrh | grep tunnel | tail"
nstage = 0
mail_addr = 'cheng.huang#qq.com'
otp_file = dir + '/otplist/C591260'
otp_list = []
rsg_file = dir + '/.rsg_hosts'
known_hosts = dir + '/.ssh/known_hosts'
rsg_port = "auto"
#-----------------------------------------
def printlog(prompt):
year, mon, mday, hour, min, sec, wday, yday, isdst = time.localtime()
print("%04d-%02d-%02d %02d:%02d:%02d %s" % (year, mon , mday, hour, min,
sec, prompt))
def get_egw_name(ref_arr, key):
for oneline in ref_arr:
if (re.search(key, oneline)):
templine = oneline
oneline = re.sub('^\s+|\s+$','',oneline)
egw_ssg = re.split('\s+',oneline)[2]
result = re.split(':',egw_ssg)[0]
return result
def sendworker(to_addr):
from_addr = 'itk-bj.ericsson.se'
smtp_server = 'smtp.eamcs.ericsson.se'
msg = MIMEText('There is no otp left ,please input new OTP list',
'plain', 'utf-8')
msg['From'] = from_addr
msg['To'] = to_addr
msg['Subject'] = Header(u'OTP List is Blank', 'utf-8')
server = smtplib.SMTP(smtp_server, 25)
#server.set_debuglevel(1)
server.sendmail(from_addr, to_addr, msg.as_string())
server.quit()
def ssh_cmd(port, target, user, ip, pasw, cmd ):
printlog("=== Script Start ===")
printlog("Monitoring via remote logon")
time.sleep(1)
ssh = pexpect.spawn('/usr/bin/ssh -p %s -o HostKeyAlias=%s %s#%s %s' %
(port, target, user, ip, cmd ),timeout=6000)
try:
i = ssh.expect(['Password: ', 'continue connecting (yes/no)?'],
timeout=15)
if i == 0 :
print(ssh.before.decode(),ssh.after.decode())
ssh.sendline(pasw)
elif i == 1:
print(ssh.before.decode(),ssh.after.decode())
ssh.sendline('yes')
ssh.expect('Password: ')
print(ssh.before.decode(),ssh.after.decode())
ssh.sendline(pasw)
except pexpect.EOF:
print ("no connection EOF,please check RSG tunnel")
except pexpect.TIMEOUT:
print ("your pexpect has TIMEOUT")
else:
ssh.expect(pexpect.EOF)
print (ssh.before.decode(),ssh.after().decode()) # if I disable this line, there will be no error.
flag = ssh.before.decode()
return flag
ssh.close()
if __name__ == '__main__':
if os.path.exists(os.environ['HOME'] + "/.ssh/known_hosts"):
os.remove(known_hosts)
else:
pass
label = ssh_cmd(nLocalport, rsg_target, ouser, lookip, opasw, command)
if re.search('tunnel_check', str(label)):
nstage = 1
if (nstage == 0):
printlog("Tunnel was down and will re-establish now\n")
rsg = open (rsg_file,'r')
rsg_in = rsg.readlines()
rsg.close()
egwname = get_egw_name(rsg_in, rsg_target)
try :
otp = open(otp_file, 'r')
otp_arrary = otp.readlines()
otp.close()
for ot in otp_arrary:
ot = ot.strip()
ot = ot.replace('^\s*|\s*$', '')
otp_list.append(ot)
otp_num = len(otp_list) + 1
if (otp_num > 0):
os.remove(rsg_file)
try :
new_otp = otp_list[0]
except IndexError:
printlog('There is no otp left ,please input new OTP list')
sendworker(mail_addr)
sys.exit()
else:
out = open(rsg_file, 'w')
for line in rsg_in :
line = line.strip()
line = line.replace('^\s+|\s+$','')
if (re.match(egwname, line)):
temp_line = line
old_otp = re.split('\s+',temp_line)[5]
old_otp = old_otp.replace('^\s+|\s+$', '')
line = line.replace(old_otp, new_otp).replace('\\','')
printlog(line + "\n")
out.write(line + "\n")
out.close()
os.remove(otp_file)
time.sleep(1)
outotp = open(otp_file , 'w+')
i = 0
while (i < len(otp_list)):
outotp.write(otp_list[i] + "\n")
i += 1
outotp.close()
os.system("pkill -9 -f \"ssh\.\*-L " + str(nLocalport) + "\"")
os.system("sleep 10")
os.system("pkill -9 -f \"rtunnel\.\*-p " + str(nLocalport) + "\"")
os.system("nohup /opt/ericsson/itk/bin/rtunnel -d -q -g -p " + str(nLocalport) + "-rp auto " + rsg_target + " &")
os.system("sleep 10")
printlog("Kill the rtunnel process\n");
printlog("Tunnel is re-established again\n");
else:
sendworker(mail_addr)
except IOError:
print ("File is not accessible.")
else:
printlog("Tunnel OK")
As you see , after disable the line in Try... else... block, the code will be OK.
else:
ssh.expect(pexpect.EOF)
print (ssh.before.decode(),ssh.after().decode()) # if I disable this line, there will be no error.
flag = ssh.before.decode()
return flag
If you look carefully your traceback, you will find the problem:
Instead of:
print (ssh.before.decode(),ssh.after().decode())
you should write
print (ssh.before.decode(),ssh.after.decode())
after is a method which return string, not a function.
BTW, I think you should put decoding/encoding in your pexpect constructor.

Python script won't run over SSH but will run locally

I am writing a small application to monitor some temperatures using a raspberry pi. I would like to be able to remotely start or restart the monitoring script remotely. I connect via SSH, cd to the .py file's directory, and then i "python temp_controller.py &". This gives me an error importing something. "from w1thermsensor import W1ThermSensor". This error does not occur when running the script from Thonny directly on the Pi.
"Main" file.
import Send_Email
import Temp_Sensor
import os
import glob
import math
import timefuncs
import apc_controls
program_start_time = timefuncs.get_time() #Used to determine how long the program has been running.
printable_start_time = timefuncs.get_printable_time()
filename = ("Temperature Data " + printable_start_time.strftime("%c") + ".txt")
state = 0 #Used to switch between activities and determine if there has been an error.
temps = [0,0,0,0,0,0,0,0],[0,0] #Holds temperature data
over_temp_counter = 0 #variable for tracking consecutive over temp values
newdir = os.getcwd() + "/temps files"; os.chdir(newdir) #Changes directory to storage location for temperature files
with open(filename, "w+") as tempsfile:
tempsfile.write("Long Term Temperature Monitor Project\r\n")
tempsfile.write("Date-Time,Sensor ID,Sensor Name,Temperature\r\n")
test = 0
while True:
if (math.floor(timefuncs.get_time())) % 30 == 0 and state == 0:
print("sample")
state = 1 #stops this from executing multiple times per second
length = Temp_Sensor.read_sensors(temps) #gets number of sensors and sensor data with IDs
#Writes data line to log file
now = timefuncs.get_printable_time()
tempsfile.write("%s"%now)
i = 0
while i < length:
print("Sensor %s has temperature %.2f" % (temps[i][0], temps[i][1]))
tempsfile.write(",%s"%temps[i][0])
tempsfile.write(",%s"%Temp_Sensor.get_sensor_name(temps[i][0]))
tempsfile.write(",%f"%temps[i][1])
i += 1
tempsfile.write("\r\n")
#Checks temperatures to see if over temp
i = 0
over = False
while i < length:
if Temp_Sensor.check_temp(temps[i][1]):#if over temp
over = True
if over_temp_counter > 1:#ensures there is not a single fluke reading that causes error
print("over temp")
tempsfile.close()#close log file
Send_Email.send_fail_email(filename)#send email with log file
apc_controls.turn_off_apc()#shut down power to test
tempsfile = open("(After error" + printable_start_time.strftime("%c") + ".txt", "w+")
else:
print("increment over")
over_temp_counter += 1
i+=1
if over == False:
over_temp_counter = 0
elif (math.floor(timefuncs.get_time())) % 30 != 0:#if not 30 second increment reset blocker used to prevent the 30 secodn operations from occuring more than once
state = 0
File with the error.
import time
import glob
from w1thermsensor import W1ThermSensor
def read_sensors(data):
i = 0
j = 0
for sensor in W1ThermSensor.get_available_sensors([W1ThermSensor.THERM_SENSOR_DS18B20]):
data[i][j] = sensor.id
j+=1
data[i][j] = sensor.get_temperature()
i+=1
j = 0
return i
def get_sensor_name(id):
if id == "000009ac911f":
return "Sensor 1"
elif id == "000009aecc36":
return "Sensor 2"
def check_temp(value):
if value > 80:
return 1
else:
return 0
I guess on your local machine you did something like pip install w1thermsensor, right? You need to install the w1thermsensor dependency on your Raspberry pi too

Target machine refused connection

from geopy.geocoders import Nominatim
import openpyxl
wb = openpyxl.load_workbook('#######.xlsx')
ws = wb.active
geolocator = Nominatim(timeout=60)
for i in range(2,1810):
count1 = 0
count2 = 1
address = str(ws['B'+str(i)].value)
city = str(ws['C'+str(i)].value)
state = str(ws['D'+str(i)].value)
zipc = str(ws['F'+str(i)].value)
result = None
iden1 = address + ' ' + city + ' ' + state
iden2 = city + ' ' + zipc + ' ' + state
iden3 = city + ' ' + state
print(iden1, iden2, iden3)
print(geolocator.geocode(iden2).address)
try:
location1 = geolocator.geocode(iden1)
except:
pass
try:
location2 = geolocator.geocode(iden2)
except:
pass
try:
location3 = geolocator.geocode(iden3)
except:
pass
count = None
try:
county1 = str(location1.address)
county1_list = county1.split(", ")
#print(county1_list)
for q in county1_list:
if 'county' in q.lower():
if count == None:
count = q
except:
pass
try:
county2 = str(location2.address)
county2_list = county2.split(", ")
#print(county2_list)
for z in county2_list:
if 'county' in z.lower():
if count == None:
count = z
except:
pass
try:
county3 = str(location3.address)
county3_list = county3.split(", ")
#print(county3_list)
for j in county3_list:
if 'county' in j.lower():
if count == None:
count = j
except:
pass
print(i, count)
#ws['E'+str(i)] = count
if count == 50:
#wb.save("#####" +str(count2) +".xlsx")
count2 += 1
count1 = 0
Hello all, this code is pretty simple and uses geopy to extract county names using 3 different methods names iden1, iden2, and iden3 which are a combination of address, city, state, and zipcode. This ran fine for about 300 lines but began to repeat the same county, and after restarting the script, just spat out Nones. I put in the line print (geolocator.geocode(iden2).address) to find the error and got this error message.
Traceback (most recent call last):
File "C:/Users/#####/Downloads/Web content/#####/####_county.py",
line 19, in
print(geolocator.geocode(iden2).address) File "C:\Users#####\AppData\Local\Programs\Python\Python36-32\lib\site-packages\geopy\geocoders\osm.py",
line 193, in geocode
self._call_geocoder(url, timeout=timeout), exactly_one File "C:\Users#####\AppData\Local\Programs\Python\Python36-32\lib\site-packages\geopy\geocoders\base.py",
line 171, in _call_geocoder
raise GeocoderServiceError(message) geopy.exc.GeocoderServiceError: [WinError 10061] No connection could
be made because the target machine actively refused it
This script was working before but now does not. Is my IP being blocked from using goepy's database or something? Thanks for your help!
It looks like you're hitting their ratelimiting. It seems that they ask that you limit your API requests to 1/second. You can take a look here for their usage policy where they list alternatives to using their API as well as contraints.

Flashing hex over a serial port to an LPC Microcontroller with Pyserial does not work

I am using Arch Linux and have not found any software that allows me to flash files onto my microcontroller. My school's documentation for flashing had a python file, and when I run it, I get the Error message root: Timed out!.
The code:
########
# CHANGELOG:
# 2016-02-15 : Working Skeleton for Flashing a Hex file to SJOne comeplete!
#
import string
import os
import time
import struct
import binascii
import math
import serial.serialutil
import logging
import sys
sys.path.append('/usr/lib/python3.5/site-packages/')
from intelhex import IntelHex
import serial
###############################################################################
################# CONFIGURATION FOR pyFlash - Hyperload ######################
###############################################################################
sDeviceFile = "/dev/ttyUSB0" # Device File Path
sDeviceBaud = 38400 # Suitable Device Baud Rate
sHexFilePath = "/SJSU_Dev2/projects/lpc1758_freertos/_build/lpc1758_freertos.hex"
sGenerateBinary = "y" # "y" - Yes | "n" - No
###############################################################################
#### LOGGING OPTIONS ####
PYFLASH_DEBUG_LOG = "no" # "yes" - Debug Version. "no" - Release Version
#########################
if PYFLASH_DEBUG_LOG == "yes":
PYFLASH_BUILD_LEVEL = "DEBUG"
else:
PYFLASH_BUILD_LEVEL = "RELEASE"
if PYFLASH_BUILD_LEVEL == "DEBUG":
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
else:
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
# Things to Do:
# 1. Display Platform Information [DONE]
# 2. Enable a Debug/Release Switch [DONE]
# 3. Create ~/.pyFlash and store last used options for Flashing [PEND]
# 4. Handle Exceptions [PEND]
# 5. Ensure packing is done based on Endianness [PEND]
# 6. Re-write program with classes using this as the backbone. [PEND]
# 7. Incorporate design decisions keeping the GUI in mind [PEND]
# Issues Faced
# 1. Handling Bytes were hard - Use bytearray for most of the IO related functions. Difference between bytes and bytearray is that the latter is mutable.
# Bytes are types that are not mutable. Any changes done on them will cause a new alloc + concat and reassigning.
# Global Defines
ApplicationVersion = "1.0"
ToolName = "pyFLASH - HYPERLOAD"
ToolInfo = "Flashing Tool for SJOne"
BaudList = [4800, 9600, 19200, 38400]
ControlWordList = b'\x80\xf8\xfe\xff'
SpecialChar = {'Dollar' : '$', 'OK' : '!', 'NextLine' : '\n', 'STAR' : '*'}
sCPUSpeed = 48000000
sInitialDeviceBaud = 38400
ByteReference = b'\xff\x55\xaa'
# Common Util Functions
def printIntroMessage():
print ("#######################")
print (" ", ToolName)
print (ToolInfo)
print ("#######################")
print ("Version : ", ApplicationVersion)
print ("Build Type : ", PYFLASH_BUILD_LEVEL)
print ("#######################")
return
def printBytes(mymsg):
print ("Type info = " + (str)(type(mymsg)))
if (type(mymsg) == bytes) or (type(mymsg) == bytearray):
for x in mymsg:
print ("0x" + '{:x}'.format(x),)
print ("")
print ("Total Elements = " + (str)(len(mymsg)))
elif (type(mymsg) == str):
printBytes(bytearray(mymsg))
elif type(mymsg) == int:
print ("0x" + '{:x}'.format(mymsg),)
else:
print (mymsg)
return
def getBoardParameters(descString):
boardParametersDict = {'Board' : '', 'BlockSize' : '', 'BootloaderSize' : '', 'FlashSize' : ''}
# Parsing String to obtain required Board Parameters
boardParametersList = descString.split(':')
boardParametersDict['Board'] = boardParametersList[0]
boardParametersDict['BlockSize'] = boardParametersList[1]
boardParametersDict['BootloaderSize'] = (int(boardParametersList[2]) * 2)
boardParametersDict['FlashSize'] = boardParametersList[3]
print ("\n***** Board Information ********")
print ("Board = " + (str)(boardParametersDict['Board']))
print ("Block (Chunk) Size = " + (str)(boardParametersDict['BlockSize']) + " bytes")
print ("Bootloader Size = " + (str)(boardParametersDict['BootloaderSize']) + " bytes")
print ("Flash Size = " + (str)(boardParametersDict['FlashSize']) + " KBytes")
print ("*********************************\n")
return boardParametersDict
def printContent(lContent):
logging.debug("--------------------")
count = 0;
totalCount = 0;
for x in lContent:
print ('{:2x}'.format(x),)
if count >= 10:
print ("\n")
count = 0
else:
count = count + 1
totalCount = totalCount + 1
logging.debug("\n--------------------")
logging.debug("Total Count = ", totalCount)
logging.debug("--------------------")
return
def getControlWord(baudRate, cpuSpeed):
# TODO : Currently using known values. Replace with actual formula
logging.debug("Retrieving Control Word")
controlWord = ((cpuSpeed / (baudRate * 16)) - 1)
return controlWord
def getPageContent(bArray, blkCount, pageSize):
startOffset = blkCount * pageSize
endOffset = (startOffset + pageSize - 1)
#print "Page Start = ", startOffset, " | Page End = ", str(endOffset)
lPageContent = bytearray(pageSize)
for x in range(0, pageSize):
lPageContent[x] = bArray[x + (blkCount * pageSize)]
#print "Length of x = ", x
if x != pageSize - 1:
raw_input()
return lPageContent
def getChecksum(blocks):
# Try older method - Add and Pack into integer.
lChecksum = bytearray(1);
for x in blocks:
lChecksum[0] = (lChecksum[0] + x) % 256
return lChecksum[0]
# Class
### Main Program ###
printIntroMessage()
print (str('-' * (len(sHexFilePath) + 20)))
print ("Hex File Path = \"" + sHexFilePath + "\"")
print (str('-' * (len(sHexFilePath) + 20)))
# Fetching Hex File and Storing
hexFile = IntelHex(sHexFilePath)
if sGenerateBinary == "y":
# Create a Binary File of this Hex File
sBinFilePath= sHexFilePath.replace(".hex", ".bin")
logging.debug("Binary File Path : %s", sBinFilePath)
hexFile.tofile(sBinFilePath, format='bin')
# Obtain the actual Binary content from the Hex File
binArray = hexFile.tobinarray()
sPort = serial.Serial(
port = sDeviceFile,
baudrate = sInitialDeviceBaud,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
bytesize = serial.EIGHTBITS)
sPort.reset_input_buffer()
sPort.reset_output_buffer()
sPort.flush()
# Setting Initial State of RTS Bit to False
sPort.rts = False;
# Reseting the board by toggling DTR
sPort.dtr = False;
# Reading a Byte from SJOne
msg = sPort.read(1)
if msg is ByteReference[1]:
sPort.write(ByteReference[1])
logging.debug("Initial Handshake Initiated! - Received ")
msg = sPort.read(1)
if msg is ByteReference[2]:
logging.debug("Received " + (str)(repr(msg)) + ", Sending Control Word..")
lControlWordInteger = getControlWord(sDeviceBaud, sCPUSpeed)
lControlWordPacked = struct.pack('<i', lControlWordInteger)
msg = sPort.write(bytearray(lControlWordPacked))
if msg != 4:
logging.error("Error - Sending control word failed")
else:
logging.debug("Sending Control Word Successful!")
msg = sPort.read(1)
if msg != lControlWordPacked[0]:
logging.error("Error - Failed to receive Control Word Ack")
else:
logging.debug("Ack from SJOne received!")
if sDeviceBaud != sInitialDeviceBaud:
# Switch to new BaudRate here.
logging.debug("Requested Baudrate different from Default. Changing Baudrate..")
sPort.baudrate = sDeviceBaud
else:
logging.debug("BaudRate same as Default")
# Read the CPU Desc String
msg = sPort.read(1)
if msg != SpecialChar['Dollar']:
logging.error("Failed to read CPU Description String")
else:
logging.debug("Reading CPU Desc String..")
CPUDescString = SpecialChar['Dollar']
while True:
msg = sPort.read(1)
if msg == SpecialChar['NextLine']:
break
CPUDescString = CPUDescString + msg
logging.debug("CPU Description String = %s", CPUDescString)
boardParameters = getBoardParameters(CPUDescString)
# Receive OK from SJOne
msg = sPort.read(1)
if msg != SpecialChar['OK']:
logging.error("Error - Failed to Receive OK")
else:
logging.debug("OK Received! Sending Block")
# Send Dummy Blocks -
# Update : We can send the actual blocks itself.
# Sending Blocks of Binary File
totalBlocks = (len(binArray) * 1.0 / int(boardParameters['BlockSize']))
logging.debug("Total Blocks = %f", totalBlocks)
paddingCount = len(binArray) - ((len(binArray)) % int(boardParameters['BlockSize']))
logging.debug("Total Padding Count = %d", paddingCount)
totalBlocks = math.ceil(totalBlocks)
print ("Total # of Blocks to be Flashed = ", totalBlocks)
# Pad 0's to binArray if required.
binArray = bytearray(binArray)
binArray += (b'\x00' * paddingCount)
blockCount = 0
sendDummy = False
#sendDummy = True
blockContent = bytearray(int(boardParameters['BlockSize']))
if sendDummy == True:
logging.debug("FLASHING EMPTY BLOCKS")
#
while blockCount < totalBlocks:
print ("--------------------")
blockCountPacked = struct.pack('<H', blockCount)
msg = sPort.write(blockCountPacked[1])
if msg != 1:
logging.error("Error in Sending BlockCountLowAddr")
msg = sPort.write(blockCountPacked[0])
if msg != 1:
logging.error("Error in Sending BlockCountHiAddr")
logging.debug("BlockCounts = %d", blockCount)
if sendDummy == False:
blockContent = getPageContent(binArray, blockCount, int(boardParameters['BlockSize']))
msg = sPort.write(blockContent)
if msg != len(blockContent):
logging.error("Error - Failed to sending Data Block Content")
break
#printContent(blockContent)
checksum = bytearray(1)
checksum[0] = getChecksum(blockContent)
logging.debug("Checksum = %d[0x%x]", checksum[0], checksum[0])
msg = sPort.write(checksum)
logging.debug("Size of Block Written = %d", msg)
if msg != 1:
logging.error("Error - Failed to send Entire Data Block")
msg = sPort.read(1)
if msg != SpecialChar['OK']:
logging.error("Failed to Receive Ack.. Retrying #" + str(blockCount))
else:
print ("Block # " + str(blockCount) + " flashed!")
blockCount = blockCount + 1
print ("--------------------")
if blockCount != totalBlocks:
logging.error("Error - All Blocks not Flashed")
logging.error("Total = " + str(totalBlocks))
logging.error("# of Blocks Flashed = " + str(blockCount))
else:
print ("Flashing Successful!")
endTxPacked = bytearray(2)
endTxPacked[0] = 0xFF
endTxPacked[1] = 0xFF
msg = sPort.write(bytearray(endTxPacked))
if msg != 2:
logging.error("Error in Sending End Of Transaction Signal")
msg = sPort.read(1)
logging.debug("Received Ack = " + str(msg))
if msg != SpecialChar['STAR']:
logging.error("Error - Final Ack Not Received")
else :
logging.error("Timed Out!")
sPort.baudrate = sInitialDeviceBaud
sPort.close()
The top half established the correct port (/dev/ttyUSB0) and turns the hex into binary, and the bottom half doing the flashing, which is the aspect that does not work.
The port (/dev/ttyUSB0) and baudrates are correct.
The timeout occurs because the program does not read an expected byte from the device:
# Reading a Byte from SJOne
msg = sPort.read(1)
if msg is ByteReference[1]:
# Programming code
# ...
else :
logging.error("Timed Out!")
You should probably use minicom to verify that you can communicate with the device. If you can communicate with minicom, try printing msg in the else clause.
In the comments, you say that printing msg yields
b'\x00'
However, ByteReference is defined as
ByteReference = b'\xff\x55\xaa'
This means that ByteReference[1] should be
b'\x55'
So msg does not match the expected value. This means the if clause that performs the programming will not be reached.

Resources