Ondilo spa/pool monitor - gjniewenhuijse - 20.10.2020
Hello,
Please, can anyone help with connecting a Ondilo spa monitor.
Authentication is to difficult for me ![Wink Wink](https://forum.logicmachine.net/images/smilies/wink.png)
Here the api info how to auth: https://interop.ondilo.com/docs/api/customer/v1/oauth.html#authentication
And here's the general api info: https://interop.ondilo.com/docs/api/customer/v1/
I have a app username and password but i see nothing in the doc how to get access to the api with that user&pwd
RE: Ondilo spa/pool monitor - gjniewenhuijse - 21.10.2020
Ok, i give it a try
my code:
Code: local usr = "my@email.com"
local pwd = "mypwd"
local uri = "https%3A%2F%2Fyour.app.url%2Fauthorize" -- there's no url redirect, so how to handle this
local state = "c7d37ee542c7'" -- random
---------------------------- change nothing after this line -------------------------------
local apiHost = "https://interop.ondilo.com"
local apiUrl = apiHost .. "/api/customer/v1"
local endpointToken = "/oauth2/token"
local endpointAuth = "/oauth2/authorize"
-- init
if not init then
require('socket.http')
require('ltn12')
require('json')
socket.http.TIMEOUT = 5
init = true
end
function getAuth()
url = apiHost..endpointAuth..'?client_id=customer_api&response_type=code&redirect_uri='..uri..'&scope=api&state='..state
method = "POST"
local response_body = { }
local payload = '{"login":"'..usr..'","password":"'..pwd..'","locale":"nl","proceed":"Authorize"}'
local res, code, response_headers, status = socket.http.request
{
url = url,
method = method,
headers =
{
["Accept"] = "application/json",
["Accept-Charset"] = "utf-8",
["Accept-Encoding"] = "gzip-deflate",
["Content-Type"] = "application/json",
["Content-Length"] = payload:len()
},
source = ltn12.source.string(payload),
sink = ltn12.sink.table(response_body)
}
log(res, code, response_headers, status)
log(response_body)
end
getAuth()
My return:
Code: * arg: 1
* number: 1
* arg: 2
* number: 200
* arg: 3
* table:
["server"]
* string: Apache/2.4.29 (Ubuntu)
["content-type"]
* string: text/html;charset=UTF-8
["connection"]
* string: close
["access-control-allow-methods"]
* string: GET, POST, PUT, PATCH, DELETE, OPTIONS
["access-control-allow-headers"]
* string: X-Requested-With, Content-Type, Accept, Origin, Authorization
["cache-control"]
* string: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0
["pragma"]
* string: no-cache
["content-length"]
* string: 4047
["date"]
* string: Wed, 21 Oct 2020 17:45:44 GMT
["vary"]
* string: Accept-Encoding
["access-control-allow-origin"]
* string:
["access-control-allow-credentials"]
* string: true
* arg: 4
* string: HTTP/1.1 200 OK
but how to get the code that is normally send to the url given in the var uri (see above) or is my code wrong?
documentation is here: https://interop.ondilo.com/docs/api/customer/v1/oauth.html#authentication
if i do the same in a browser, my return url looks like:
https://your.app.url/authorize?code=644075xxxxxxd071b67xxxxxxcccb4a88c&state=c7d37ee542c7
RE: Ondilo spa/pool monitor - admin - 22.10.2020
What do you get in response body? You should also remove Accept-Encoding header otherwise body will be compressed with gzip instead of plain text.
RE: Ondilo spa/pool monitor - gjniewenhuijse - 22.10.2020
(22.10.2020, 06:30)admin Wrote: What do you get in response body? You should also remove Accept-Encoding header otherwise body will be compressed with gzip instead of plain text.
I see the plain website, i think the form is not filled and executed. But how to do this.
same source as:
https://interop.ondilo.com/oauth2/authorize?client_id=customer_api&response_type=code&redirect_uri=https%3A%2F%2Fyour.app.url%2Fauthorize&scope=api&state=c1d44ef532c5
Code: * table:
[1]
* string:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Ondilo authorization page</title>
<style>
* {
margin: 10px 4px 10px 4px;
}
.box {
width: 340px;
margin: auto;
border: 1px solid rgb(41, 165, 155);
}
.banner {
margin: 0px;
background-color: rgb(41, 165, 155);
height: 50px;
position: relative;
}
.ico {
position: absolute;
top: 3px;
left: 4px;
}
.ondilo {
position: absolute;
top: -1px;
right: 4px;
}
strong {
margin: 0px;
}
label {
margin-top: 8px;
margin-bottom: 0px;
display: block;
font-size: 0.8em;
color: gray;
}
input, select {
font-size: 1.2em;
}
input[type=text], input[type=password], select {
width: 312px;
}
input[type=submit] {
width: 322px;
display: block;
margin-bottom: 25px;
}
.authorize {
color: white;
background-color: rgb(41, 165, 155);
margin-bottom: 10px;
margin-top: 25px;
border-color: rgb(41, 165, 155);
}
p {
text-align: center;
margin-top: 25px;
margin-bottom: 25px;
}
.warning p, .warning ul {
margin: 0 0 0 0;
line-height: 15px;
}
</style>
</head>
<body>
<div class="box">
<div class="banner">
<img src="/images/ico.png" alt="ICO" title="ICO" class="ico"/
[2]
* string: >
<img src="/images/ondilo.png" alt="Ondilo" title="Ondilo" class="ondilo"/>
</div>
<form method="post">
<p>Sign in to allow <strong>customer_api</strong> to connect to your <strong>Ondilo</strong> account and access the related data</p>
<label for="login">Your email address</label><input type="text" name="login" ><br/>
<label for="pasword">Your password</label><input type="password" name="password">
<label for="locale">Your language</label><select id="locale" name="locale">
<option value="en">English</option>
<option value="fr">Français</option>
<option value="es">Español</option>
<option value="de">Deutsch</option>
<option value="pt">Português</option>
<option value="nl">Nederlands</option>
<option value="it">Italiano</option>
<option value="cs">Čeština</option>
<option value="hu">Magyar</option>
<option value="sv">Svenska</option>
<option value="ro">Română</option>
</select>
<div class="warning">
<p>
We remind that ICO takes measures every hour.</br>
In order to avoid excessive load of our servers, the requests to the Ondilo Customer API are limited to the following per user quotas :
<ul>
<li>5 requests per second</li>
<li>30 requests per hour</li>
</ul>
</p>
</div>
<input type="submit" name="proceed" value="Authorize" class="authorize">
<input type="submit" name="proceed" value="Cancel">
</form>
</div>
</body>
</html>
RE: Ondilo spa/pool monitor - admin - 22.10.2020
For auth you need to use standard POST, not JSON:
Code: function encodepost(t)
local res = {}
local esc = require('socket.url').escape
for k, v in pairs(t) do
res[ #res + 1 ] = esc(k) .. '=' .. esc(v)
end
return table.concat(res, '&')
end
payload = encodepost({
login = usr,
password = pwd,
locale = "nl",
proceed = "Authorize",
})
For this request Accept/Content-Type headers are not needed. Add redirect = false to the request table to catch the redirect URL instead of following it.
RE: Ondilo spa/pool monitor - gjniewenhuijse - 22.10.2020
(22.10.2020, 07:14)admin Wrote: For auth you need to use standard POST, not JSON:
For this request Accept/Content-Type headers are not needed. Add redirect = false to the request table to catch the redirect URL instead of following it.
mmm same result with changed code
Code: function getAuth()
function encodepost(t)
local res = {}
local esc = require('socket.url').escape
for k, v in pairs(t) do
res[ #res + 1 ] = esc(k) .. '=' .. esc(v)
end
return table.concat(res, '&')
end
url = apiHost..endpointAuth..'?client_id=customer_api&response_type=code&redirect_uri='..uri..'&scope=api&state='..state
method = "POST"
local response_body = {}
local payload = encodepost({
login = usr,
password = pwd,
locale = "nl",
proceed = "Authorize",
})
local res, code, response_headers, status = socket.http.request
{
url = url,
method = method,
redirect = false,
headers =
{
["Content-Length"] = #payload
},
source = ltn12.source.string(payload),
sink = ltn12.sink.table(response_body)
}
if res and code == 200 then
log(response_body)
log(res, code, response_headers, status)
else
log(res, code, response_headers, status)
end
end
RE: Ondilo spa/pool monitor - admin - 22.10.2020
Header is missing:
Code: ["Content-Type"] = "application/x-www-form-urlencoded"
RE: Ondilo spa/pool monitor - gjniewenhuijse - 22.10.2020
(22.10.2020, 08:23)admin Wrote: Header is missing:
Code: ["Content-Type"] = "application/x-www-form-urlencoded"
yes, now i get the authorization code (authCode).
Next is exchaging the authorization code for an access token, see my code try below.
Doc: https://interop.ondilo.com/docs/api/customer/v1/oauth.html#authentication-token-exchange
Code: -- exchange the authorization code for an access token
if authCode then
url = apiHost..endpointToken..'?code='..authCode..'&grant_type=authorization_code&client_id=customer_api&redirect_uri='..uri
method = "POST"
local response_body = {}
local res, code, response_headers, status = socket.http.request
{
url = url,
method = method,
headers =
{
["Content-Type"] = "application/x-www-form-urlencoded"
},
source = ltn12.source.string(''),
sink = ltn12.sink.table(response_body)
}
log(res, code, response_headers, status)
end
but as usually i received an error
Code: * arg: 1
* number: 1
* arg: 2
* number: 400
* arg: 3
* table:
["server"]
* string: Apache/2.4.29 (Ubuntu)
["content-type"]
* string: application/json
["connection"]
* string: close
["access-control-allow-methods"]
* string: GET, POST, PUT, PATCH, DELETE, OPTIONS
["access-control-allow-headers"]
* string: X-Requested-With, Content-Type, Accept, Origin, Authorization
["cache-control"]
* string: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0
["pragma"]
* string: no-cache
["date"]
* string: Thu, 22 Oct 2020 11:14:32 GMT
["content-length"]
* string: 97
["access-control-allow-origin"]
* string: *
["access-control-allow-credentials"]
* string: true
* arg: 4
* string: HTTP/1.1 400 Bad Request
RE: Ondilo spa/pool monitor - admin - 22.10.2020
You must provide "Content-Length" header for POST requests. Move your GET variables to POST payload:
Code: url = apiHost..endpointToken
payload = encodepost({
code = authCode,
grant_type = 'authorization_code',
client_id = 'customer_api',
redirect_uri = uri,
})
RE: Ondilo spa/pool monitor - gjniewenhuijse - 22.10.2020
many thanks to admin for the support.
here my first version to get the latest sensor readings for one pool/spa.
We remind that ICO takes measures every hour.
In order to avoid excessive load of our servers, the requests to the Ondilo Customer API
are limited to the following per user quotas :
5 requests per second
30 requests per hour
Access tokens have a lifetime of one hour, while refresh tokens are non-expiring.
RE: Ondilo spa/pool monitor - admin - 23.10.2020
One small improvement, you should use the whole table instead of only the first element. If the JSON response is large enough then the response table will have more than 1 element. Use this instead:
Code: data = json.decode(table.concat(response_body))
RE: Ondilo spa/pool monitor - MikeBrignate - 21.05.2021
Hello
Could you give some instructions with examples how to get sensors data please ![Shy Shy](https://forum.logicmachine.net/images/smilies/shy.png)
I am not familiar with scripting, but can multiply solution from example.
Thank you
RE: Ondilo spa/pool monitor - admin - 24.05.2021
First you need to set usr and pwd variables in the script. Then run this function to get the ID of your pool:
Code: log( getPoolInfo() )
Then you can request the sensor state by calling getSensorInfo:
Code: data = getSensorInfo()
log(data)
When the data format is known the script can be modified to write sensor state to objects.
RE: Ondilo spa/pool monitor - MikeBrignate - 25.05.2021
(24.05.2021, 09:38)admin Wrote: First you need to set usr and pwd variables in the script. Then run this function to get the ID of your pool:
Code: log( getPoolInfo() )
Then you can request the sensor state by calling getSensorInfo:
Code: data = getSensorInfo()
log(data)
When the data format is known the script can be modified to write sensor state to objects.
Hello
I have got sensors data, thank you, could you make example of a function for the PUT method?
Thank you
RE: Ondilo spa/pool monitor - admin - 25.05.2021
PUT is the same as POST, just change the method field accordingly
|