HttpPost Error

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
CookieNinja
Posts: 3
Joined: Mon May 16, 2022 8:57 am

HttpPost Error

Post by CookieNinja » Thu May 19, 2022 9:24 am

Can someone maybe help me and tell me what the problem can be. I'm connecting my Pico via a Pico-ESP8266 wave wifi HAT and the connection is fine when connecting to either my laptop or phone hotspot. Then when I try to send Ubidots a httpPost on port 9012 I get an error of List index is out of range (Code follows). When I change the port number to 80, then I don't get the error. But obviously it also doesn't send through any data. Anyone maybe know whats happening

Main-1.py:

Code: Select all

from machine import UART, Pin, I2C, PWM, SPI
from esp8266 import ESP8266
import time, sys, utime
from secret import AP_SSID, AP_Pwd, DataBase_URL, DataBase_Secret, Firebase_ProjectName, Web_API
from PicoLCD import LCD_1inch14

print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("RPi-Pico MicroPython Ver:", sys.version)
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
    

#Credentials
SSID=AP_SSID
Pass=AP_Pwd
DB_URL=DataBase_URL
DB_Secret=DataBase_Secret



## Create On-board Led object
led=Pin(25,Pin.OUT)



## Create an ESP8266 Object
esp01 = ESP8266()
esp8266_at_ver = None



'''
Test communication to ESP8266
'''
print("Communication: ",esp01.startUP())
while (esp01.startUP() == True):

    break;

print("StartUP",esp01.startUP())
#print("ReStart",esp01.reStart())
print("StartUP",esp01.startUP())
print("Echo-Off",esp01.echoING())
print("\r\n\r\n")

'''
Print ESP8266 AT comand version and SDK details
'''
esp8266_at_ver = esp01.getVersion()
if(esp8266_at_ver != None):
    print(esp8266_at_ver)

'''
set the current WiFi in SoftAP+STA
'''
esp01.setCurrentWiFiMode()
#apList = esp01.getAvailableAPs()
#for items in apList:
#    print(items)
    #for item in tuple(items):
    #    print(item)
  
print("\r\n\r\n")

'''
Connect with the WiFi
'''


print("Try to connect with the WiFi..")
while (1):
    if "WIFI CONNECTED" in esp01.connectWiFi(SSID,Pass):
        print("ESP8266 connect with the WiFi..")

        break;
    else:
        print(".")
        time.sleep(2)


print("\r\n\r\n")
print("Now it's time to start Communication to Ubidots\r\n")

while(1):   

    led.toggle()

    time.sleep(1)

    '''

    Going to do HTTP Post Operation with industrial.api.ubidots.com/post

    '''

    post_json="UbidotsESP8266/1.0|POST|BBFF-5zUpQ1TOUpcMyYitTu75gaitbNOGjT|sennah=>tempC:21.42667,tempF:70.56801|end"  #"{\"name\":\"Noyel\"}"

    httpCode, httpRes = esp01.doHttpPost("industrial.api.ubidots.com","/post","RPi-Pico", "application/json",post_json,port=9012)

    print("------------- www.httpbin.org/post Post Operation Result -----------------------")

    print("HTTP Code:",httpCode)

    print("HTTP Response:",httpRes)

    print("--------------------------------------------------------------------------------\r\n\r\n")

    #break
Terminal Response:

Code: Select all

Traceback (most recent call last):
  File "<stdin>", line 97, in <module>
  File "esp8266.py", line 496, in doHttpPost
  File "httpParser.py", line 35, in parseHTTP
IndexError: list index out of range


Line 97:      httpCode, httpRes = esp01.doHttpPost("industrial.api.ubidots.com","/post","RPi-Pico", "application/json",post_json,port=9012)


Line 496 (The specific line is inbetween the ๐Ÿ˜Ž): def doHttpPost(self,host,path,content_type,content,user_agent="RPi-Pico",port=9012):
        """
        This fucntion use to complete a HTTP Post operation
        
        Parameter:
            host (str): Host URL [ex: get operation URL: www.httpbin.org/ip. so, Host URL only "www.httpbin.org"]
            path (str): Get operation's URL path [ex: get operation URL: www.httpbin.org/ip. so, the path "/ip"]
            user-agent (str): User Agent Name [Default "RPi-Pico"]
            content_type (str): Post operation's upload content type [ex. "application/json", "application/x-www-form-urlencoded", "text/plain"
            content (str): Post operation's upload content 
            post (int): HTTP post number [Default port number 80]
        
        Return:
            HTTP error code & HTTP response[If error not equal to 200 then the response is None]
            On failed return 0 and None
        
        """
        if(self._createTCPConnection(host, port) == True):
            self._createHTTPParseObj()
            postHeader="POST "+path+" HTTP/1.1\r\n"+"Host: "+host+"\r\n"+"User-Agent: "+user_agent+"\r\n"+"Content-Type: "+content_type+"\r\n"+"Content-Length: "+str(len(content))+"\r\n"+"\r\n"+content+"\r\n";
            #print(postHeader,len(postHeader))
            txData="AT+CIPSEND="+str(len(postHeader))+"\r\n"
            retData = self._sendToESP8266(txData)
            if(retData != None):
                if ">" in retData:
                    retData = self._sendToESP8266(postHeader, delay=2)
                    print(".......@@",retData)            
                    self._sendToESP8266("AT+CIPCLOSE\r\n")
                    print(self.__httpResponse)
                    retData=self.__httpResponse.parseHTTP(retData)
                  ๐Ÿ˜Ž  return retData, self.__httpResponse.getHTTPResponse() ๐Ÿ˜Ž
                else:
                    return 0, None
            else:
                return 0, None
        else:
            self._sendToESP8266("AT+CIPCLOSE\r\n")
            return 0, None

Line 35(Same as previous, with ๐Ÿ˜Ž):     
def parseHTTP(self, httpRes):
        """
        This funtion use to parse the HTTP response and return back the HTTP status code
        
        Return:
            HTTP status code.
        """
        #print(">>>>",httpRes)
        if(httpRes != None):
            retParseResponse=str(httpRes).partition("+IPD,")[2]
            #print(">>>>>>>>>>>>>>>>>",retParseResponse)
            retParseResponse=retParseResponse.split(r"\r\n\r\n");
            #print(">>>>>>>>>>>>>>>>>",retParseResponse[0])
           ๐Ÿ˜Ž self.__httpResponse = retParseResponse[1]๐Ÿ˜Ž
            #print(">>>>>>>>>>>>>>>>>???",retParseResponse[1])  
            self.__httpHeader=str(retParseResponse[0]).partition(":")[2]
            #print("--",self.__httpHeader)
            for code in str(self.__httpHeader.partition(r"\r\n")[0]).split():
                if code.isdigit():
                    self.__httpErrCode=int(code                    
            if(self.__httpErrCode != 200):
                self.__httpResponse=None
                
            return self.__httpErrCode
        else:
            return 0
               

User avatar
karfas
Posts: 193
Joined: Sat Jan 16, 2021 12:53 pm
Location: Vienna, Austria

Re: HttpPost Error

Post by karfas » Thu May 19, 2022 9:39 am

Code: Select all

           retParseResponse=retParseResponse.split(r"\r\n\r\n");
            #print(">>>>>>>>>>>>>>>>>",retParseResponse[0])
           ๐Ÿ˜Ž self.__httpResponse = retParseResponse[1]๐Ÿ˜Ž
Obviously your split() returns only one array element.
I assume this is caused by the usage of the r"\r\n\r\n" raw string - there the \n means a backslash followed by a 'n', not the ASCII newline character, as I just learned from https://stackoverflow.com/questions/208 ... g-literals :
A "raw string literal" is a slightly different syntax for a string literal, in which a backslash, \, is taken as meaning "just a backslash"
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

Post Reply