ESP8266/NodeMCU RESTful HTTP 发布
ESP8266/NodeMCU RESTful HTTP posting
以下代码在 ESP8266 微控制器上运行,post通过 HTTP 将基本传感器读数流发送到 Ubidots 网络服务 API。使用了 NodeMCU Lua 解释器(我想在 Lua 中使用它,现在不想使用其他替代方案,例如 Arduino IDE 或 MicroPython。)
"sensor data" 似乎有效(现在是虚拟的),post 读数的计时器事件似乎有效,我认为 JSON 的格式和结构 POST基本正确,wifi连接好像是正确的,但数据最终到达云端dashboard的不是。
我认为我在设置 POST 语法时做了一些愚蠢的事情。
我希望有新的眼睛来发现错误。
WIFI_SSID = "foo_ssid"
WIFI_PASSWORD = "secret_password"
API_TOKEN = "secret_ubidots_token"
update_period = 5 -- seconds
function format_json(variable1, value1, variable2, value2, variable3, value3)
-- let's allow three different readings in the nested JSON payload.
data = '{'..variable1..': {"value": '..value1..'},'
..variable2..': {"value": '..value2..'},'
..variable3..': {"value": '..value3..'}}'
return data
end
function postUbidots(deviceName, name1, value1, name2, value2, name3, value3)
connection_out = nil
connection_out = net.createConnection(net.TCP, 0)
connection_out:on("receive", function(connection_out, payload_out)
if (string.find(payload_out, "201 CREATED") ~= nil) then
print("POST OK");
end
end)
connection_out:on("connection", function(connection_out, payload_out)
data = format_json(name1, value1, name2, value2, name3, value3)
local post_string = "POST /api/v1.6/devices/"..deviceName.."/?token="
..API_TOKEN.." HTTP/1.1\n"
.."Host: things.ubidots.com\n"
.."Content-Type: application/json\n"
.."Content-Length: "..string.len(data).."\n"
..data.."\n"
connection_out:send(post_string)
end)
connection_out:on("disconnection", function(connection_out, payload_out)
connection_out:close();
collectgarbage();
end)
connection_out:connect(80, 'things.ubidots.com')
end
function readSensors()
-- don't worry about real sensors right now
-- let's just make up a few dummy variables.
sensor1_value = 90
sensor2_value = 65
sensor3_value = 30
postUbidots("deviceName", "sensor1", sensor1_value, "sensor2", sensor2_value, "sensor3", sensor3_value)
end
wifi.setmode(wifi.STATION)
wifi.setphymode(wifi.PHYMODE_G)
station_config={}
station_config.ssid=WIFI_SSID
station_config.pwd=WIFI_PASSWORD
station_config.auto=true
wifi.sta.config(station_config)
tmr.alarm(1, 1000, 1, function()
if wifi.sta.getip() == nil then
else
tmr.stop(1)
end
end)
print("WiFi connected.")
tmr.alarm(1, (update_period*1000), tmr.ALARM_AUTO, function() readSensors() end)
问题在于您如何格式化 HTTP 消息。试试这个:
local post_string = "POST /api/v1.6/devices/"..deviceName.."/?token="
..API_TOKEN.." HTTP/1.1\r\n"
.."Host: things.ubidots.com\r\n"
.."Content-Type: application/json\r\n"
.."Content-Length: "..string.len(data).."\r\n\r\n"
..data..
参考:https://nodemcu.readthedocs.io/en/latest/en/modules/net/#netsocketsend
您知道我们有一个专用的 HTTP 模块可以大大简化操作吗?
-> https://nodemcu.readthedocs.io/en/latest/en/modules/http/#httppost
以下代码在 ESP8266 微控制器上运行,post通过 HTTP 将基本传感器读数流发送到 Ubidots 网络服务 API。使用了 NodeMCU Lua 解释器(我想在 Lua 中使用它,现在不想使用其他替代方案,例如 Arduino IDE 或 MicroPython。)
"sensor data" 似乎有效(现在是虚拟的),post 读数的计时器事件似乎有效,我认为 JSON 的格式和结构 POST基本正确,wifi连接好像是正确的,但数据最终到达云端dashboard的不是。
我认为我在设置 POST 语法时做了一些愚蠢的事情。
我希望有新的眼睛来发现错误。
WIFI_SSID = "foo_ssid"
WIFI_PASSWORD = "secret_password"
API_TOKEN = "secret_ubidots_token"
update_period = 5 -- seconds
function format_json(variable1, value1, variable2, value2, variable3, value3)
-- let's allow three different readings in the nested JSON payload.
data = '{'..variable1..': {"value": '..value1..'},'
..variable2..': {"value": '..value2..'},'
..variable3..': {"value": '..value3..'}}'
return data
end
function postUbidots(deviceName, name1, value1, name2, value2, name3, value3)
connection_out = nil
connection_out = net.createConnection(net.TCP, 0)
connection_out:on("receive", function(connection_out, payload_out)
if (string.find(payload_out, "201 CREATED") ~= nil) then
print("POST OK");
end
end)
connection_out:on("connection", function(connection_out, payload_out)
data = format_json(name1, value1, name2, value2, name3, value3)
local post_string = "POST /api/v1.6/devices/"..deviceName.."/?token="
..API_TOKEN.." HTTP/1.1\n"
.."Host: things.ubidots.com\n"
.."Content-Type: application/json\n"
.."Content-Length: "..string.len(data).."\n"
..data.."\n"
connection_out:send(post_string)
end)
connection_out:on("disconnection", function(connection_out, payload_out)
connection_out:close();
collectgarbage();
end)
connection_out:connect(80, 'things.ubidots.com')
end
function readSensors()
-- don't worry about real sensors right now
-- let's just make up a few dummy variables.
sensor1_value = 90
sensor2_value = 65
sensor3_value = 30
postUbidots("deviceName", "sensor1", sensor1_value, "sensor2", sensor2_value, "sensor3", sensor3_value)
end
wifi.setmode(wifi.STATION)
wifi.setphymode(wifi.PHYMODE_G)
station_config={}
station_config.ssid=WIFI_SSID
station_config.pwd=WIFI_PASSWORD
station_config.auto=true
wifi.sta.config(station_config)
tmr.alarm(1, 1000, 1, function()
if wifi.sta.getip() == nil then
else
tmr.stop(1)
end
end)
print("WiFi connected.")
tmr.alarm(1, (update_period*1000), tmr.ALARM_AUTO, function() readSensors() end)
问题在于您如何格式化 HTTP 消息。试试这个:
local post_string = "POST /api/v1.6/devices/"..deviceName.."/?token="
..API_TOKEN.." HTTP/1.1\r\n"
.."Host: things.ubidots.com\r\n"
.."Content-Type: application/json\r\n"
.."Content-Length: "..string.len(data).."\r\n\r\n"
..data..
参考:https://nodemcu.readthedocs.io/en/latest/en/modules/net/#netsocketsend
您知道我们有一个专用的 HTTP 模块可以大大简化操作吗? -> https://nodemcu.readthedocs.io/en/latest/en/modules/http/#httppost