[SOLVED] 400 Bad Request using lua w/ ESP8266


#1

Hi! I’ve just been working through the example code at https://ubidots.com/docs/api/#values using the http module in lua.
I’m new to lua so this could totally be my fault, but I’m at a loss so far. I’m able to grab an Auth token no problem with almost identical code. I’m not sure what I’m missing, considering my request should be similar to the example in the margin.

Here’s the calling function and vars(stripped down).
ubd.apiAccessUri=“http://things.ubidots.com
ubd.deviceId=“5978f766c03f9771c6414dec”
ubd.postVarUri="/api/v1.6/devices/"…ubd.deviceId
ubd.token=nil
ubd.writeVar=function(var,val)
if ubd.token==nil then
ubd.getToken()
tmr.alarm(2,1000, 1, function()
if ubd.token~=nil then
tmr.stop(2)
ubd.writeVar(var,val)
end
end)
else
body=[[{"]]…var…[[": ]]…val…[[}]]
headrs=table.concat({
“X-Auth-Token: “…ubd.token, – set in getToken, see ex request and response
“Content-Length: “…#body,
“Content-Type: application/json”,
},”\r\n”)
–print(“Request\r\n”…ubd.apiAccessUri…ubd.postVarUri)
–print(headrs)
–print(body)
http.post(
ubd.apiAccessUri…ubd.postVarUri,
headrs,
body,
function(code,data)
print(”\r\nResponse\r\n”…code…data)
end)
end
end

Here’s a request and response.
Request
http://things.ubidots.com/api/v1.6/devices/5978f766c03f9771c6414dec
X-Auth-Token: A1E-cHoXQuaSSER9reAYxGoTqRe2udC6QNRSOpzG7ifm6Z8wvWRA2jBs2aM8
Content-Length: 18
Content-Type: application/json
{“servoVal”: 1000}

Response
400<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

And finally here’s live output including all the print lines i stripped from the function.


#2

Also I cannot edit the post (constant 500s) to fix the code formatting. The preformat button didn’t help at all.


#3

Greetings @Myroden, I’ve checked your issue and the TOKEN A1E-cHoXQuaSSER9reAYxGoTqRe2udC6QNRSOpzG7ifm6Z8wvWRA2jBs2aM8 does not exist in our database, that is why your request is rejected. Please check your TOKEN again and try the request one more time.

Here you can find how to find the TOKEN inside your account: http://help.ubidots.com/ubidots-app/find-your-token-from-your-ubidots-account

Regards


#4

Myroden, were you able to solve this problem? I am also trying to figure out the easiest way to submit IoT sensor values to Ubidots using ‘lua’, and so far your code is one of the few ‘real life’ examples attempting to do this. Thanks!


#5

Hi there, this code snippet may serve you as reference

function sendValue(value,token,varID)
srv = net.createConnection(net.TCP, 0)
srv:connect(80,"things.ubidots.com")
print("Sending POST")

-- Waits for connection befor of sending values
srv:on("connection", function(sck, c) token = c return token end)


var = '{"value": '..dato..'}';
num = string.len(var);
local cadenaPOST = "POST /api/v1.6/variables/"..varID.."/values
HTTP/1.1\r\n"
.."Content-Type: application/json\r\n"
.."Content-Length: "..num.."\r\n"
.."X-Auth-Token: "..token .."\r\n"
.."Host: things.ubidots.com\r\n\n"
..var.."\r\n";
sck:send(cadenaPOST)
end)

srv:close();
end

Hope it helps you


#6

Thanks jotathebest! With your guidance, I have now been able to do this – including altering the syntax to allow sending multiple readings at one time :slight_smile:

My next concern is that I hope to find a way to target specific variables by ‘name’ instead of by their generated ‘id’ values. If I create multiple devices (say, for friends), I don’t want to hard-code these identifiers – at most I would like to fill in a unique ‘token’ value for them, and let the variables be identified by static names (if you know what I mean).

EDIT: I was able to figure out how to reference variable names by ‘name’ instead of ‘id’ :slight_smile:


#7

Hi @darethehair, I am glad to know that you figured out how to reference by variable name, can you share with the community your solution for future references?

Thanks in advise


#8

Sure, here is my code snippet, showing me sending values to my ‘T’, ‘H’, ‘P’, and ‘D’ variables (by name):

ubitoken=‘my-ubi-token-string’

ubivars = ‘{“T”:’ … string.format("%.3f", t) … ', ’ …
‘“H”:’ … string.format("%.3f", h) … ', ’ …
‘“P”:’ … string.format("%.3f", q) … ', ’ …
‘“D”:’ … string.format("%.3f", d) … ‘}’
ubivarslen = string.len(ubivars);
param = “POST /api/v1.6/devices/my-device-label/?token=”…ubitoken…" HTTP/1.1\r\n"
…“Content-Type: application/json\r\n”
…“Content-Length: “…ubivarslen…”\r\n”
…“Host: things.ubidots.com\r\n\n”
…ubivars…"\r\n";