Posts: 451
Threads: 94
Joined: Jun 2015
Reputation:
6
Hello,
Please, can anyone help with connecting a Ondilo spa monitor.
Authentication is to difficult for me
Here the api info how to auth:
https://interop.ondilo.com/docs/api/cust...entication
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
Posts: 451
Threads: 94
Joined: Jun 2015
Reputation:
6
21.10.2020, 17:53
(This post was last modified: 21.10.2020, 18:29 by gjniewenhuijse .)
Ok, i give it a try
my code:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
local usr =
"my@email.com"
local pwd =
"mypwd"
local uri =
"https%3A%2F%2Fyour.app.url%2Fauthorize"
local state =
"c7d37ee542c7'"
local apiHost =
"https://interop.ondilo.com"
local apiUrl =
apiHost ..
"/api/customer/v1"
local endpointToken =
"/oauth2/token"
local endpointAuth =
"/oauth2/authorize"
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
*
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/cust...entication
if i do the same in a browser, my return url looks like:
https://your.app.url/authorize?code=6440...a88c&state =
c7 d3 7 ee54 2c 7
Posts: 8072
Threads: 43
Joined: Jun 2015
Reputation:
471
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.
Posts: 451
Threads: 94
Joined: Jun 2015
Reputation:
6
(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/author...d44ef532c5
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
*
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 >
Posts: 8072
Threads: 43
Joined: Jun 2015
Reputation:
471
For auth you need to use standard POST, not JSON:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
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.
Posts: 451
Threads: 94
Joined: Jun 2015
Reputation:
6
(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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
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
Posts: 8072
Threads: 43
Joined: Jun 2015
Reputation:
471
Header is missing:
Code:
1
[
"Content-Type" ] =
"application/x-www-form-urlencoded"
Posts: 451
Threads: 94
Joined: Jun 2015
Reputation:
6
(22.10.2020, 08:23) admin Wrote: Header is missing:
Code:
1
[
"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/cust...n-exchange
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
*
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
Posts: 8072
Threads: 43
Joined: Jun 2015
Reputation:
471
You must provide "Content-Length" header for POST requests. Move your GET variables to POST payload:
Code:
1 2 3 4 5 6 7
url =
apiHost..endpointToken
payload =
encodepost ({
code =
authCode ,
grant_type =
'authorization_code' ,
client_id =
'customer_api' ,
redirect_uri =
uri ,
})
Posts: 451
Threads: 94
Joined: Jun 2015
Reputation:
6
22.10.2020, 16:43
(This post was last modified: 23.10.2020, 06:39 by gjniewenhuijse .)
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.
Attached Files
Posts: 8072
Threads: 43
Joined: Jun 2015
Reputation:
471
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:
1
data =
json.decode (
table.concat (
response_body ))
Posts: 6
Threads: 2
Joined: Oct 2018
Reputation:
0
Hello
Could you give some instructions with examples how to get sensors data please
I am not familiar with scripting, but can multiply solution from example.
Thank you
Posts: 8072
Threads: 43
Joined: Jun 2015
Reputation:
471
First you need to set usr and pwd variables in the script. Then run this function to get the ID of your pool:
Then you can request the sensor state by calling getSensorInfo:
Code:
1 2
data =
getSensorInfo ()
log (
data )
When the data format is known the script can be modified to write sensor state to objects.
Posts: 6
Threads: 2
Joined: Oct 2018
Reputation:
0
(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:
Then you can request the sensor state by calling getSensorInfo:
Code:
1 2
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
Posts: 8072
Threads: 43
Joined: Jun 2015
Reputation:
471
PUT is the same as POST, just change the method field accordingly