Can I use the Domoticz JSON API from a webpage hosted on a different device? Topic is solved

Topics (not sure which fora)
when not sure where to post, post here and mods will move it to right forum.

Moderators: leecollings, remb0

Post Reply
Timmiej93
Posts: 64
Joined: Saturday 26 December 2015 0:37
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Can I use the Domoticz JSON API from a webpage hosted on a different device?

Post by Timmiej93 »

I've got two Raspberry Pi's running. One is my main system, running Domoticz, the other one is connected to a touchscreen, which I'm making into a sort of custom control panel.
To control some Domoticz stuff from that second RPi, I obviously need to use the JSON API, but I'm running into some issues, so i'm wondering: Can the JSON API even be used in code for a webpage that is hosted on a different device? And if it's possible, is some kind of CORS proxy required?
User avatar
Egregius
Posts: 2582
Joined: Thursday 09 April 2015 12:19
Target OS: Linux
Domoticz version: v2024.7
Location: Beitem, BE
Contact:

Re: Can I use the Domoticz JSON API from a webpage hosted on a different device?

Post by Egregius »

I would run a webserver, or use the builtin webserver, on the domoticz server.
On the second rpi with touchscreen just use a browser to view that site.
That way you can also make that site available for every other smartphone or tablet in the house.

And yes, of course you can use the JSON api for this.
Timmiej93
Posts: 64
Joined: Saturday 26 December 2015 0:37
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Can I use the Domoticz JSON API from a webpage hosted on a different device?

Post by Timmiej93 »

Sometimes you just keep overthinking things, when the simple solution is the best. Thanks!
EDIT: I forgot, CORS is also an issue when you're accessing domoticz from the same machine, since you're on a different port, so unfortunately this won't work either.

Now I'm curious though, if I did want to host the webpage on a different machine, what would I need to do to be able to use the JSON API from that different machine?

I have managed to do it before, but there both Domoticz and the webpage are hosted under the same URL, which gets converted to localhost:port in the Apache VirtualHosts. I've been looking through that file, but I really can't find anything that would fix the CORS issue, since the virualhost is basically saying "URL/subdomain goes to localhost:port, and URL/otherSubdomain goes to localhost:otherPort". Why that wouldn't trigger CORS is beyond me.
User avatar
Egregius
Posts: 2582
Joined: Thursday 09 April 2015 12:19
Target OS: Linux
Domoticz version: v2024.7
Location: Beitem, BE
Contact:

Re: Can I use the Domoticz JSON API from a webpage hosted on a different device?

Post by Egregius »

I have no clue at all what you're saying. The problem could be that you let javascript handle a url on a different host than the site, correct? I think that you can solve CORS with extra headers.

I host my own floorplan in Apache2. The communication is done locally between the webserver and domoticz, not between the browser and domoticz.
So my clients only need access to 1 webserver and my domoticz gui isn't exposed to the internet.
Timmiej93
Posts: 64
Joined: Saturday 26 December 2015 0:37
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Can I use the Domoticz JSON API from a webpage hosted on a different device?

Post by Timmiej93 »

Yes, I'm trying to do an API call on the webpage. So on webpage 192.168.0.254:9000 I'm trying to call 192.168.0.254:8080/DomoticzAPICall. CORS is preventing this.
Normally, this would be fixable with the Access-Control-Allow-Origin header. For Domoticz, this is set to "*", allowing everything. However, since you need to authorize, an error is thrown, since you can't have the Access-Control-Allow-Origin header set to "*" when you need to authorize. Here's the error in the browser:

Code: Select all

Access to XMLHttpRequest at 'http://192.168.0.254:8080/json.htm?type=command&param=switchscene&idx=2&switchcmd=On/' 
from origin 'http://192.168.0.254:9000' has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header 
in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
As far as I know, I can't change anything CORS related on the browser end, and changing hardcoded things in the Domoticz.sh file doesn't seem like a great idea either.
User avatar
Egregius
Posts: 2582
Joined: Thursday 09 April 2015 12:19
Target OS: Linux
Domoticz version: v2024.7
Location: Beitem, BE
Contact:

Re: Can I use the Domoticz JSON API from a webpage hosted on a different device?

Post by Egregius »

Put a PHP page on 192.168.0.254:9000 that sends the call to 192.168.0.254:8080 internally.
User avatar
Egregius
Posts: 2582
Joined: Thursday 09 April 2015 12:19
Target OS: Linux
Domoticz version: v2024.7
Location: Beitem, BE
Contact:

Re: Can I use the Domoticz JSON API from a webpage hosted on a different device?

Post by Egregius »

Something like this should do:

Code: Select all

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://192.168.0.254:8080/json.htm");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_REQUEST));
$data = curl_exec($ch);
curl_close($ch);
Timmiej93
Posts: 64
Joined: Saturday 26 December 2015 0:37
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Can I use the Domoticz JSON API from a webpage hosted on a different device?

Post by Timmiej93 »

Since I'm not that familiar with PHP, I decided to first take a look at the things I did in Apache (since my other webpage does work just fine). Turns out that if you Proxy the API calls through (for example) 192.168.0.254:9000/domoticz/APICall instead of 192.168.0.254:8080/APICall, and setup Apache to handle this, everything is just hunky dory. I haven't got a clue why, but it works.

Apparently, it's as simple as adding this in the Apache VirtualHost that runs (or whatever it does) your webpage:

Code: Select all

ProxyPassMatch 		/domoticz/(.*) 				http://127.0.0.1:8080/$1 keepalive=On
ProxyPassReverse 		/domoticz/(.*) 				http://127.0.0.1:8080/$1 keepalive=On
Of course, you'd need to correct for your own IP address and port for Domoticz. The '/domoticz/(.*)' section is customizable. '/domoticz/' makes it easily recognisable for Apache that this is a URL it needs to handle. The '(.*)' selects everything that comes after '/domoticz/', and captures it in group 1. Selecting everything is done with '.*', capturing is done with the brackets '()'. This captured data is then placed in the URL on the right: 'http://127.0.0.1:8080/$1'. Since the '/domoticz/' part isn't being captured, it doesn't show in the URL on the right.

This way, '192.168.0.254:9000/domoticz/thisWorksJustFine' is converted into '127.0.0.1:8080/thisWorksJustFine' by Apache. If you replace 'thisWorksJustFine' with an API call, it'll work just fine.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest