It’s complicated …
To simplify either
- Get Everything from VERA
- Get Everything from your WWW Server (i.e. a PHP server) and have that Server be a proxy for your Vera.
It’s complicated …
To simplify either
Yes, t seems strangely complicated, particularly since I can make an http request from any browser on the network and get the json or html return.
The complications are for security … so you can’t have some JavaScript hacker stealing data from a Server (i.e. Vera).
But anyone with a browser can do anything else?
This is within my private network. Currently, I can get data from Vera from any browser. I can also set any setting from any web browser…
I just can’t understand how it somehow translates to higher security. If this was the public internet, I’d understand ( like Vera’s old security).
I’m missing something here, I think.
All I want to do is parse the JSON object that I’m already freely receiving.
Can my website spoof a browser and get a return?
???
OK @RichardTSchaefer ,
I had a thought, how about a simple XMLHttpRequest() [edit] or JsonHttpRequest [edit]? Would I be subject to the same CORS type security issues?
YES! They all go through the same low level JavaScript API that will NOT let you do this.
Use one of the two options I mentioned earlier …
Other options are way to complicated to describe and get correct without a LOT of experimenting.
Got it thanks.
Can you explain why a simple web browser doesn’t have any of these security issues?
What makes the browser different from any other call to the (Vera) server?
I understand when I make a call to a webserver (e.g. Weather underground) that I simply pass the security params with the call to get my JSON or xml response.
I can also pass credentials to Google’s Atom feed and get my email in html format. Does Vera’s API allow for the obvious HUGE security leaks (e.g. http requests can get or set) but tries to contain a JavaScript hacking? It seems to me like locking the barn open.
When the Browser points to Vera … it gets the HTML and JavaScript and Data from Vera … there is NO cross site scripting.
When you point the Browser at the Vera Remote Access … It provides the HML, JavaScript and Data … there Server acts as a Proxy to the real Vera.
Right, pushing on then… I’m going in the Proxy direction.
Someone gave me a link to this Node.JS proxy as a possible solution.
This will be stretch for my limited skills!
Well, after enough poking around I found a Node.js library called: reverse-proxy.
install it using npm:
npm install -g reverse-proxy-js
and I set up the proxy like this:
reverse-proxy -h 127.0.0.1 -p 8080 -t 10.0.1.25:3480
i.e. reverse-proxy -h -p -t<TARGET_SERVER> // note the target’s port appended to the target server’s IP
and then you can make a call to the proxy like this in your browser to confirm:
http://127.0.0.1:8080/data_request?id=status&output_format=json&DeviceNum=3
and from your html like this:
<!DOCTYPE HTML>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript" ></script>
<script type="text/javascript">
setInterval(function()
{
veraURL = "http://127.0.0.1:8080/data_request?id=status&output_format=json&DeviceNum=3";
$.getJSON(veraURL, function(veraData){
document.getElementById("jsonReturn").innerHTML = JSON.stringify(veraData);
}, myTest());
}, 5000);
function myTest()
{
console.log("Success")
//alert("Success");
}
</script>
</head>
<body>
<P>Vera Ajax Test<br><br>
<br>
<br>
<p>getJSON return: <div id="jsonReturn">Fetching...</div><br></p>
</body>
</html>
returns the same json as the browser call!!!
Thanks for the clues…
Hopefully this will help someone out there building some Ajax supported web interface!
Now… onto parsing this big boy for my AJAX enabled web server!!!
Hi
I’ve been trying learn how I can retrieve a variable value from Vera and format it with HTML - I can see the origin rule mentioned a few times, but have come across this from Stack Overflow.
[code]
Javascript can be used, as long as you grab whatever page you’re after via a proxy on your domain:
I’m just looking for my internal web server - 192.168.1.123 to retrieve a variable via a http request from my Vera at 192.168.1.234 - I assume they are not considered to be within the same domain ?
Shouldn’t be a CORS issue here - they’re the same domain. Simple GET request should work with no problems?
As documented here: http://wiki.micasaverde.com/index.php/Luup_Requests#variableget
[b]variableget[/b]http://ip_address:3480/data_request?id=variableget&DeviceNum=6&serviceId=urn:micasaverde-com:serviceId:DoorLock1&Variable=Status
If you leave off the DeviceNum and serviceID, then this gets a top-level json tag called “Variable”.
Thanks @akbooer
I had actually already tried to rework a web widget I liked with that request, but it did not work for me. Here is the full code I’ve been working on…
[code]
<style type="text/css" media="screen">
@font-face
{
font-family: "Roadgeek2005SeriesD";
src: url("/fonts/Roadgeek 2005 Series D.otf");
}
body, *
{
}
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td
{
margin: 0;
padding: 0;
}
fieldset,img
{
border: 0;
}
/* Settin' up the page */
html, body, #main
{
overflow: hidden; /* */
}
body
{
color: white;
font-family: 'Roadgeek2005SeriesD', sans-serif;
font-size: 20px;
line-height: 24px;
}
body, html, #main
{
background: transparent !important;
}
#spacepeopleContainer
{
width: 250px;
height: 250px;
text-align: center;
background-size: 250px 187px;
}
#spacepeopleContainer *
{
font-weight: normal;
}
h1
{
font-size: 120px;
line-height: 120px;
margin-top: 15px;
margin-bottom: 28px;
color: white;
text-shadow:0px -2px 0px black;
text-transform: uppercase;
}
h2
{
width: 180px;
margin: 0px auto;
padding-top: 24px;
font-size: 16px;
line-height: 18px;
color: #7e7e7e;
text-transform: uppercase;
}
#device_name {
font-size: 36px;
color: rgba(0, 108, 230, 1);
}
h3#vera
{
width: 180px;
margin: 0px auto;
padding-top: 20px;
font-size: 24px;
line-height: 16px;
color: rgba(241, 42, 22, 1);
font-weight: normal;
}
</style>
</head>
<body onload="updateCal()">
<div id="main">
<div id="spacepeopleContainer">
<h3 id="vera"></h3>
<h2 id="device_name"></h2>
<h1 id="temp"></h1>
</div><!-- spacepeopleContainer -->
</div><!-- main -->
</body>
function updateCal() {
var VeraName = document.getElementById("vera")
var veraDevice = document.getElementById("device_name")
var veraTemp document.getElementById("temp").innerHTML=newValue;
var request = new XMLHttpRequest();
var url = 'http://192.168.1.234:3480/data_request?id=variableget&DeviceNum=237&serviceId=urn:upnp-org:serviceId:TemperatureSensor1&Variable=CurrentTemperature&output_format=json';
request.open('GET', url);
request.send();
VeraName.innerHTML = 'Vera Home Control';
VeraName.innerHTML = 'Office Room Temp';
}
</script>
[/code]
I just get a blank page when I run this - so hopefully someone with way more HTML/JavaScript skill than I could help. The goal is just to have three rows of text, with the 3rd row showing the temp from Vera.
There are a couple problems.
You define a function to initiate the transfer … But never call it. Maybe you need to add a REFRESH button that can call this function.
In that function you set the third row from a variable that has not been initialized. In fact it can’t be set in this function block.
You have not defined the completion routine for the URL. The result is not available except in a completion routine or block. That’s where you set up the third row variable.
Thanks @ RTS
Regarding…
I thought that was covered by this line of code - is it not ?
<body onload="updateCal()">
I missed that … can’t remember the initialization order using vanilla JavaScript.
I do not know if onload is to soon.
You want to do it when the DOM is ready.
I usually use JQuery and it handles these details as well as the browser specific initialization quirks.
I’m stumped now on how to get my temperature widget to work. ???
If it helps anyone, here’s the javascript that I used as the basis for mine, this one which was presenting the date, day of the week and month works.
[code]
<div id="spacepeopleContainer">
<h3 id="dow"></h3>
<h2 id="month"></h2>
<h1 id="day"></h1>
</div><!-- spacepeopleContainer -->
</div><!-- main -->
</body>
<script type="text/javascript" charset="utf-8" async defer>
function updateCal() {
var weekday = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
var months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
var todayObj = new Date();
var docDow = document.getElementById("dow")
var docMonth = document.getElementById("month")
var docDay = document.getElementById("day")
docDow.innerHTML = weekday[todayObj.getDay()];
docMonth.innerHTML = months[todayObj.getMonth()];
docDay.innerHTML = todayObj.getDate();
}
</script>[/code]
So I messed around with this (as you can see above) and ended up with a series of calls to my Vera through a PHP proxy, because of its ease of use.
My proxy is in the same directory as my html web app and looks as simple as this (called proxy.php):
<?php
$url = $_REQUEST['url'];
if (preg_match('/\b(https?|ftp):\/\/*/', $url) !== 1) die;
echo (file_get_contents($url));
?>
you can see at this moment:
window.onload = function() {
document.body.style.cursor = "default";
startTime();
getParticleData();
getLocalTemp();
getLocalHumidity();
getLocalDewPoint();
loadVeraData();
}
I then make calls for Vera data like this:
function loadVeraData()
{
console.log("loading data from server...");
$.ajax({
type: 'GET',
url: "http://10.0.1.15/proxy.php?url=http%3A%2F%2F10.0.1.25%2Fport_3480%2Fdata_request%3Fid%3Dstatus%26output_format%3Djson",
data: {},
dataType: "json",
success: function(data){
processThermostats(data);
processVeraSliders(data);
processVeraToggles(data);
}
});
}
pay close attention to the URI I’m passing as a variable to the PHP script, it is encoded, because it must be.
I am getting ALL of the status here in a JSON which I handle in the three functions looking for three different device types, but here is the thermostat function which retrieves the setpoint, current temperature and the status (I only use A/C here but you can easily add the logic for heat).
[code]
//data
thermostat = [
{“deviceNum”:3, “setpointTag”:“hallSetpoint”, “currentTag”:“hallCurrent”, “activeTag”:“hallSnowflake”, “reading”:“range2”, “sliderValue”:“tstatRange2”},
{“deviceNum”:69, “setpointTag”:“guestSetpoint”, “currentTag”:“guestCurrent”, “activeTag”:“guestSnowflake”, “reading”:“range3”, “sliderValue”:“tstatRange3”},
{“deviceNum”:4, “setpointTag”:“mbrSetpoint”, “currentTag”:“mbrCurrent”, “activeTag”:“mbrSnowflake”, “reading”:“mbrRange”, “sliderValue”:“mbrSliderVal”}
];
//function
function processThermostats(data){
console.log(“getting thermostat data…”);
for(var i = 0; i < 2; i++)
{
var device = data.devices.filter(function(chunk) {return chunk.id === thermostat[i].deviceNum;});
var foundTemp = device[0].states.filter(function(item) {return item.variable === “CurrentTemperature”;});
var temp = (foundTemp[0].value);
var foundSetpoint = device[0].states.filter(function(item) {return item.variable === “CurrentSetpoint”;});
var setpoint = (foundSetpoint[0].value);
var foundActive = device[0].states.filter(function(item) {return item.variable === “ModeState”;});
var isActive = (foundActive[0].value);
document.getElementById(thermostat[i].currentTag).innerHTML = temp;
document.getElementById(thermostat[i].setpointTag).innerHTML = setpoint;
document.getElementById(thermostat[i].activeTag).style.visibility = (isActive === “Cooling” ? “visible” : “hidden”);
document.getElementById(thermostat[i].reading).innerHTML = setpoint;
document.getElementById(thermostat[i].sliderValue).value = setpoint;
}
}[/code]
It is all working well, but I am still relying on refreshing with the entire update JSON. When I get the chance I’ll lighten the load with functions that update on net changes…
for anyone interested in the work here, I’m happy to provide all of the code.
Thanks for sharing @Bulldoglowell
As all my requests for my temperature widget needs are going to be within the same domain it seems I don’t need a proxy etc.
Based on the code I shared earlier in this thread do you have any idea how I can just get my simple temp widget to work ? Here’s the JavaScript part below…
[code]
function updateCal() {
var VeraName = document.getElementById("vera")
var veraDevice = document.getElementById("device_name")
var veraTemp document.getElementById("temp").innerHTML=newValue;
var request = new XMLHttpRequest();
var url = 'http://192.168.1.234:3480/data_request?id=variableget&DeviceNum=237&serviceId=urn:upnp-org:serviceId:TemperatureSensor1&Variable=CurrentTemperature&output_format=json';
request.open('GET', url);
request.send();
VeraName.innerHTML = 'Vera Home Control';
VeraName.innerHTML = 'Office Room Temp';
}
</script>
[/code]
Well, that was my issue. I (like you) am working on a server on the same domain but I still had to proxy the request. You can easily just look at your web browser’s console and see if the cross domain bits are working. If not, you should see it in the error log, so double check there.
Beyond that, your function doesn’t seem to be handling a return from the call to the server.
What are you returning (what kind of object… i.e. JSON) and how to handle it…
posting the JSON response would help if you are having trouble parsing that.
Best Home Automation shopping experience. Shop at Ezlo!
© 2024 Ezlo Innovation, All Rights Reserved. Terms of Use | Privacy Policy | Forum Rules