Send data from Pico W to InfluxDB via urequest - http

I want to save the wind measurement i record with my raspberry pico w in the InfluxDB, that is hosted on my Raspberry Pi 4b with http-requests. For that i am using the urequest-library
def send_data_to_influxdb(speed):
data = '"Windmeasure,location=outdoor windspeed=' + str(speed) + ' $(date +%s%N)"'
url = 'http://192.168.178.46:8086/write?db=iobroker'
username = 'user_iobroker'
password = '{pwd}'
url = 'http://' + username + ':' + password + '#192.168.178.46:8086/write?db=iobroker'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
try:
response = urequests.post(url, headers=headers, data=data.encode())
except Exception as e:
print("Error sending data to InfluxDB: ", e)
else:
if response.status_code != 204:
print("Error sending data to InfluxDB. Response code: ", response.status_code)
else:
print("Data sent successfully to InfluxDB.")
response.close()
I get the following error:
Error sending data to InfluxDB: invalid syntax for integer with base 10
How does it work correctly?

Related

Translate a working curl request into HTTP

I'm using curl to perform a POST request, but I can't assume my target platform to have curl available, so I'm trying to rewrite my curl request in HTTP (which is guaranteed to be available). My knowledge of both curl and HTTP is very limited, so I'm hoping someone can point out what I'm doing wrong.
My curl request (command line):
curl.exe POST https://xxxxxx.ingest.sentry.io/api/xxxxxxx/minidump/?sentry_key=xxxxxxxxxxxxxxxxxxxxxxx -F upload_file_minidump=#"C:\path\Minidump.dmp" -F upload_file_log=#"C:\path\program.log"
A relevant part of curl's output is shown below. This is after connecting to the server and sending it the POST request. The server now lets the client know the first file can be sent, and curl responds first by sending the file's own header, and then the data (clamped here)
<= Recv header, 23 bytes (0x17)
0000: HTTP/1.1 100 Continue
=> Send data, 175 bytes (0xaf)
0000: --------------------------f2a4a742c08bf427
002c: Content-Disposition: form-data; name="upload_file_minidump"; fil
006c: ename="UE4Minidump.dmp"
0085: Content-Type: application/octet-stream
00ad:
=> Send data, 16384 bytes (0x4000)
0000: MDMP..a..... .......m/S`.........................;..............
0040: 8Z......T...=...........`.......8...........T................[..
0080: .........\...........]..........= ..............................
00c0: ....................................aJ.......`......Lw..........
0100: ............T........?..i/S`........ ... ... ............ ......
0140: ............G.M.T. .S.t.a.n.d.a.r.d. .T.i.m.e...................
0180: ................................G.M.T. .D.a.y.l.i.g.h.t. .T.i.m.
01c0: e...................................................1.9.0.4.1...
..etc..
By reading the verbose output of curl, I've created a HTTP request looking like this (c++ code using unreal engine 4 libraries):
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> httpRequest = FHttpModule::Get().CreateRequest();
httpRequest->SetURL(TEXT("https://xxxxxx.ingest.sentry.io/api/xxxxxx/minidump/?sentry_key=xxxxxxxxxxxxxxxxxxxxxxxx"));
httpRequest->SetVerb(TEXT("POST"));
const FString boundary(TEXT("------------------------f2a4a742c08bf427"));
httpRequest->SetHeader(TEXT("Content-Type"), TEXT("multipart/form-data; boundary=") + boundary);
const FString fileName(FPaths::Combine(path, crashToReport.folderName, TEXT("UE4Minidump.dmp")));
ensure(FPaths::FileExists(fileName));
const FString prefixBoundary(TEXT("\r\n--") + boundary + TEXT("\r\n"));
const FString fileHeader(TEXT("Content-Disposition: form-data; name=\"upload_file_minidump\"; filename=\"UE4Minidump.dmp\"\r\nContent-Type: application/octet-stream\r\n\r\n"));
FString fileContents;
FFileHelper::LoadFileToString(fileContents, *fileName);
const FString suffixBoundary(TEXT("\r\n--") + boundary + TEXT("--\r\n"));
const FString content(prefixBoundary + fileHeader + fileContents + suffixBoundary);
httpRequest->SetContentAsString(content);
This works to a degree, the server now accepts this, and will receive the file - however the file ends up being unreadable server-side, leading me to think I'm not sending it in the right format.
What kind of data is expected in a multipart/form-data request?
A thing I notice is that the curl request sends the file's header separately (the first chunk of 175 bytes). I would love some information on how to achieve that!
I finally figured it out. I'm not sure how to report what I was doing wrong, but I think it had to do with what happens under the hood in:
httpRequest->SetContentAsString(..)
, which reliably caused the backend to fail to interpret the binary file I was trying to send. I ended up reading the binary file .. as a binary file:
TArray<uint8> dumpFileData;
FFileHelper::LoadFileToArray(dumpFileData, *FPaths::Combine(path,crashToReport.folderName, TEXT("UE4Minidump.dmp")));
Then send it via the POST request, similarly as before, but adding the complete form data part as binary data:
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> httpRequest = FHttpModule::Get().CreateRequest();
httpRequest->SetURL(TEXT("https://xxxxx.ingest.sentry.io/api/xxxxxx/minidump/?sentry_key=xxxxxxxxxxxxxxxxxxxxxxxxxxx"));
httpRequest->SetVerb(TEXT("POST"));
const FString boundary(TEXT("------------------------bb33b671b1212234"));
httpRequest->SetHeader(TEXT("Content-Type"), TEXT("multipart/form-data; boundary=") + boundary);
httpRequest->SetHeader(TEXT("Accept"), TEXT("*/*"));
httpRequest->SetHeader(TEXT("Expect"), TEXT("100-continue"));
{
const FString prefixBoundary(TEXT("--") + boundary + TEXT("\r\n"));
const FString fileHeader(TEXT("Content-Disposition: form-data; name=\"upload_file_minidump\"; filename=\"UE4Minidump.dmp\"\nContent-Type: application/octet-stream\r\n\r\n"));
const FString suffixBoundary(TEXT("\r\n--") + boundary + TEXT("--\r\n"));
TArray<uint8> CombinedContent;
CombinedContent.Append(FStringToUint8(prefixBoundary + fileHeader));
CombinedContent.Append(dumpFileData);
CombinedContent.Append(FStringToUint8(suffixBoundary));
httpRequest->SetContent(CombinedContent);
}
httpRequest->ProcessRequest();
For completeness, FStringToUint8 is defined as follows:
// Convert FString to UTF8 and put it in a TArray
TArray<uint8> FStringToUint8(const FString& InString)
{
TArray<uint8> OutBytes;
// Handle empty strings
if (InString.Len() > 0)
{
FTCHARToUTF8 Converted(*InString); // Convert to UTF8
OutBytes.Append(reinterpret_cast<const uint8*>(Converted.Get()), Converted.Length());
}
return OutBytes;
}

Here server 503 response

I have created an application in python to simulate a route and than extract speed limits from the Here data extension API. The route is long 3 days driving with 8 hours per day. When I run my application for the hole route I get in some point a 503 server response instead of a 200. If I try my application for the same route where I receive the bad server response but for shorter route (2 hours route) it works Ok. It looks like a bottleneck in the server.
if self.country in WEE:
url = "http://rme.cit.api.here.com/2/matchroute.json?" + \
"app_id=Gxxxxxx" + \
"&app_code=xxxxxx" + \
"&routemode=car&file=" + \
"&regions=WEU&release=LATEST"
else:
url = "http://rme.cit.api.here.com/2/matchroute.json?" + \
"app_id=xxxxx" + \
"&app_code=Qxxxxx" + \
"&routemode=car&file=" + \
"&regions=EEU&release=LATEST"
if self.gps_source == 'gpx':
response = self.connectPost(url, self.tmp_route_data, headers={"Content-type": "application/binary"})
else:
response = self.connectPost(url, self.tmp_route_data, headers={"Content-type": "text/csv"})
if response.status_code != 200:
message = 'Unable to build the route:<br>'
message += 'unexpected response from HERE webservice.'
raise RuntimeError(message)
def connectPost(self, url, data, headers=None):
return self.S.post(url, data=data, headers=headers , proxies = self.proxy_dict)
The Customer Integration Testing(CIT) should be used for low-volume integration and functional testing. HERE doesn't provide the SLA for CIT environment.
Both the Production and CIT environments are not designed to support sudden, unannounced high loads. If you need to do performance testing, contact HERE to discuss options.

How to send a mail via SMTPS using the curl package in R?

I would like to send a mail using SMTPS in R. Currently, non of the available packages supports sending Mails via TLS (rmail & sendmaileR) or they have a hard to install Java dependency (mailr). I tried using curl and managed to send a mail using the following code snippet:
curl --url 'smtps://mail.server.com:465' --ssl-reqd --mail-from 'mail1#example.com' --mail-rcpt 'mail2#example.com' --upload-file mail.txt --user 'user:password'
Unfortunately, I could not translate that snippet into R using the brilliant curl package. While I managed to find all options, the curl statement crashes the R session every time. Furthermore, I was not able to add the mail.txt file to the request which I created in a temporary directory. Did someone manage sending mails using the curl package? Why does the program always crash? The goal should be to send mails on all platforms.
# input variables
to <- "mail1#example.com"
from <- Sys.getenv("MAIL_USER")
password <- Sys.getenv("MAIL_PASSWORD")
server <- Sys.getenv("MAIL_SERVER")
port <- 465
subject <- "Test Mail"
message <- c("Hi there!",
"This is a test message.",
"Cheers!")
# compose email body
header <- c(paste0('From: "', from, '" <', from, '>'),
paste0('To: "', to, '" <', to, '>'),
paste0('Subject: ', subject))
body <- c(header, "", message)
# create tmp file to save mail text
mail_file <- tempfile(pattern = "mail_", fileext = ".txt")
file_con <- file(mail_file)
writeLines(body, file_con)
close(file_con)
# define curl options
handle <- curl::new_handle()
curl::handle_setopt(handle = handle,
mail_from = from,
mail_rcpt = to,
use_ssl = TRUE,
port = port,
userpwd = paste(from, password, sep = ":"))
con <- curl::curl(url = server, handle = handle)
open(con, "r")
close(con)
# delete file
unlink(mail_file)

LUA: parse multi-line variable and cut needed string

I have next nginx location with Lua code (used with nginx lua-resty-redis):
location = /healthcheck {
content_by_lua_block {
local red = redis:new()
used_mem_limit = 536870912
-- connect to redis
ok, err = red:connect(ngx.var.redis_host, 6379)
if not ok then
ngx.log(ngx.ERR, "Redis connection error: ", err)
ngx.status = 500
return
end
-- setting connection timeout
red:set_timeout(1000)
-- getting redis used_memory_rss
memory = red:info('memory')
red_used_memory = ...
-- set response code
if (red_used_memory >= used_mem_limit) then
http_code = 500
elseif (red_used_memory < used_mem_limit)
http_code = 200
else
http_code = 500
end
ngx.status = http_code
}
}
memory variable should be like this:
# Memory
used_memory:105157968
used_memory_human:100.29M
used_memory_rss:110387200
used_memory_rss_human:105.27M
used_memory_peak:105219456
used_memory_peak_human:100.35M
used_memory_peak_perc:99.94%
used_memory_overhead:32290608
used_memory_startup:487168
used_memory_dataset:72867360
used_memory_dataset_perc:69.62%
total_system_memory:1044770816
I need to get used_memory_rss value, so then I can compare it with used_mem_limit. So, I don't know, how to complete red_used_memory = ... line.
There seems to be only digits in possible value so use a simple regexp and then convert resulting string to number:
red_used_memory = tonumber(memory:match('used_memory_rss:(%d+)'))
Line breaks are irrelevant.

lua with Nginx : bad argument to 'getNewSessionID' (string expected, got nil)

I have compiled nginx with Lua. and i am facing a problem .
When i hit localhost i get an error in nginx error logs
2015/05/29 07:41:32 [error] 112#0: *1 lua entry thread aborted: runtime error: /opt/hello.lua:11: bad argument #1 to 'getNewSessionID' (string expected, got nil)
stack traceback:
coroutine 0:
[C]: in function 'getNewSessionID'
Nginx configurations are
location / {
default_type 'text/html';
content_by_lua_file /opt/hello.lua;
}
And my hello.lua look like
package.path = package.path ..';/opt/?.lua'
JSON = (loadfile "/opt/JSON.lua")()
local proxyFunctions = require("proxyCode")
coherenceNGIXLocation = "/coherence"
local coherenceCookie = proxyFunctions.getExistingSessionID()
-- To Create a coherance Session if not present
if (not coherenceCookie or coherenceCookie == '') then
-- ngx.log(ngx.INFO,"No Coherence Session Exists, Creating New")
local uidCookieValueEncoded = proxyFunctions.base64Encode(str,proxyFunctions.getNewSessionID())
local sessCreateResponse = proxyFunctions.coherencePut('{"sessionToken":"'..uidCookieValueEncoded..'"}')
local parsedJSON= JSON:decode(sessCreateResponse.body)
ngx.log(ngx.INFO, "Coherence Session Create")
ngx.log(ngx.INFO, "\n\n\n=============Coherence Res==============\n\n\n"..sessCreateResponse.body.."\n\n\n=============Coherence Res==============\n\n\n")
end
local client_cookie = ngx.req.get_headers()["cookie"]
-- To Create a coherance Session if not present
ngx.log(ngx.DEBUG, "\n\n\n=============REQ==============\n\n\n"..proxyFunctions.deepPrint(ngx.req.get_headers()).."\n\n\n=============REQ==============\n\n\n")
-- Set the cookie for the legacy request
ngx.req.set_header('cookie', client_cookie)
ngx.log(ngx.INFO, "\n\n\n=============REQ URI==============\n\n\n"..ngx.var.request_uri.."\n\n\n=============REQ URI==============\n\n\n")
local legacy_res = ngx.location.capture("/app"..ngx.var.request_uri, { share_all_vars = true })
ngx.log(ngx.DEBUG, "\n\n\n=============APP Res==============\n\n\n"..proxyFunctions.deepPrint(legacy_res.header).."\n\n\n=============APP Res==============\n\n\n")
if (legacy_res.status == 302) then
ngx.redirect(legacy_res.header.Location )
else
ngx.log(ngx.INFO, "Passing the Page/Layout to Maken")
local dev_res_encoded = legacy_res.body
dev_res_encoded = ngx.escape_uri(dev_res_encoded)
-- ngx.req.set_header('Cookie', ngx.req.get_headers()["cookie"])
-- ngx.req.set_header("Content-Type", "text/html") -- application/x-www-form-urlencoded -- 'page='..dev_res_encoded
ngx.req.set_header('cookie', client_cookie) -- maken/render
-- legacy_res.header('Content-Length', legacy_res.header['Content-Length']);
local maken_res = ngx.location.capture("/maken/", {method = ngx.HTTP_POST, body = legacy_res.body, share_all_vars = true} )
ngx.header['Set-Cookie'] = legacy_res.header["Set-Cookie"]
ngx.log(ngx.INFO, "Sending Back Maken Response to Client/Browser with Cookies from lagacy")
ngx.say(maken_res.body)
end
My proxyCode.lua looks like
function _M.getNewSessionID()
-- strip the sessionID length 11 cookie name before putting into the session
-- return string.sub(ngx.var.uid_set,11)
return _M.removeCookieSessionPrefixname(ngx.var.uid_set,11)
end
function _M.removeCookieSessionPrefixname(cookieName)
return string.sub(cookieName,11)
end
function _M.getIncomingAuthToken()
local cookie = ngx.req.get_headers()["Cookie"]
if (cookie ~=nil) then
local str = string.match(cookie,"AuthToken=(.*)$")
if (str ~= nil) then
return string.sub(str,11)
end
end
return nil
end
Can someone help me why i am getting this error ? i am new to Lua programming. and trying to run legacy application on my laptop.

Resources