Tag Archives: Interface

Creating a custom HTML front end for Domoticz Part 4 – YouTube companion article

You can click here for the related YouTube video.

My previous front end for Domoticz was very well received, thank you to everyone who asked for a copy or gave feedback.  I was encouraged to create a simpler to implement but still good-looking design.

The new look is based upon primarily grey and black, with the occasional flash of red or green.  This scheme can be changed easily in the css file of course.  The whole front end has been designed to look great on landscape tablets and portrait smartphones alike.

The front end has been primarily designed to work closely with Domoticz and has several options to insert onto the screen.  The options have been specifically designed to look different to each other even though through Domoticz they would look very much the same.  This is because people who do not routinely use Domoticz generally prefer a little variation in their screen to help them navigate functions.

The functions that look different are:

Feedback switch: Lights up a segment to the right when switch is on and remains dark when off.  Can be pressed anywhere to toggle the switch.

Non-feedback button: A large button which (usually) will switch on a Domoticz switch.  Can be used to activate things like scenes or timed functions such as heating boost.

Temperature / Humidity: Shows in readable text the status of a multifunction sensor.

Sensor: Provides colour feedback on the status of the sensor as well as data on when the sensor was last seen by the system (so for door sensors and doorbells etc this shows the last time the item was used).

Navigation bar: Shows icons which are used to help the user group and navigate across the web app.  Icons were obtained from Flaticon.com and therefore without providing different icons this code cannot be used for commercial gain.

The screen is set up in two ways depending on the orientation of the screen.

Landscape – used for tablet installations: the main section is to the left, with groups of switches in a smaller column to the right.

Portrait – used on smartphones: main screen is at the top of the visible screen, with groups of switches or sensors at the rear of the screen, provided in two columns.

The code is available to download and improve over on github at https://github.com/fountside/domoticz-tiles-user-interface  so you can access copies whenever you like.  You will need the css and at least one html page to get started, then use the elements and change the variables stated at the beginning of the page to match your own setup.  I would encourage anyone who improves this code to publish it within the repository so that others (including me!) can benefit from it.

From feedback I have recently received from readers and YouTube followers, it looks like Domoticz requires the security protocols to be in place, and this version has security built in.  You’ll need to convert your username and password into base64 (follow the instructions on the Domoticz page https://www.domoticz.com/wiki/Domoticz_API/JSON_URL’s to do this).

The only additional type of html document is specifically for Sonos using node-sonos-http-api.  If you already use this then all you’ll need to do is change the variables at the start of the HTML in the audio.htm file to match your rooms set up.  From this screen you can directly control individual rooms (click on the room name to change) and there is a clear graphical display showing album art.  You can launch your favourites and skip tracks.

I hope that this design work and code is of use to you, it is the next iteration of a long-term project of mine to design a near-perfect user interface for the smart home.

 

Advertisement

Creating a custom HTML front end for Domotiz Part 3 – YouTube companion article

We’re going to get a bit more clever now. When we have taught Domoticz a list of devices (be they switches or lights or door contacts) we may want to list them all in one go without manually entering a long list of html for each device. Also, if we can get the HTML front end to gather all the information about each switch, it means that we can update the contents of the buttons automatically, for example if we change the name of a device, it will automatically update in the HTML front end.

I’ve created some code to do this and the commentary on this is over on my YouTube video.

Here’s the code and two css files that you’ll need. Please note that the css files contain more than is needed at the moment: however the css will be needed in future articles.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<head>
<title>Home Control</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />

<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<link rel="shortcut icon" href="favicon.ico" />
	<link rel="apple-touch-icon" href="iphone-icon.png"/>
	<link rel="icon" sizes="196x196" href="logo.png">
	<link rel="icon" sizes="192x192" href="logo192.png">
	<link rel="stylesheet" media="(orientation: portrait)" href="portrait.css">
	<link rel="stylesheet" media="(orientation: landscape)" href="landscape.css">
	<link href="https://fonts.googleapis.com/css?family=Baloo|Comfortaa" rel="stylesheet">

<script language="JavaScript" type="text/JavaScript">
<!--
<!--

var devicestodisplay =[36,35,31,141,32,134,132,29,136,140,33,1617];
var nod=0;
var domoticzurl="192.168.1.163";
var domoticzport="8080";

function speak(textToSpeak) {
 // Create a new instance of SpeechSynthesisUtterance
 var newUtterance = new SpeechSynthesisUtterance();

 // Set the text
 newUtterance.text = textToSpeak;

 // Add this text to the utterance queue
 window.speechSynthesis.speak(newUtterance);
}

function switchon(devicecode){
 execute('PUT', 'http://'+domoticzurl+':'+domoticzport+'/json.htm?type=command&param=switchlight&idx='+devicecode+'&switchcmd=On', '');
}

function switchoff(devicecode){
 execute('PUT', 'http://'+domoticzurl+':'+domoticzport+'/json.htm?type=command&param=switchlight&idx='+devicecode+'&switchcmd=Off', '');
}

function toggle(devicecode){
 execute('PUT', 'http://'+domoticzurl+':'+domoticzport+'/json.htm?type=command&param=switchlight&idx='+devicecode+'&switchcmd=Toggle', '');
}

function dim(devicecode,dimlevel){
 execute('PUT', 'http://'+domoticzurl+':'+domoticzport+'/json.htm?type=command&param=switchlight&idx='+devicecode+'&switchcmd=Set%20Level&level='+dimlevel, '');
}


function execute($method,$url,$message){
xmlhttp=new XMLHttpRequest();
xmlhttp.open($method,$url,true)
xmlhttp.send($message);
}
window.onload = function() {
 // all of your code goes in here
 // it runs after the DOM is built

 //updateweather();
 getalldevices();
 updatealldevices();
 }
 
window.setInterval(function(){
 updatealldevices();
 }, 1000);



function updatedevice(idx){
 var location="DEVICE"+idx;
 console.log("checking status of idx "+idx);
 var xmlhttp = new XMLHttpRequest();
 var url = 'http://'+domoticzurl+':'+domoticzport+'/json.htm?type=devices&rid='+idx;
 var onoff;
 xmlhttp.onreadystatechange = function() {
 if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
 var myArr = JSON.parse(xmlhttp.responseText);
 onoff = myArr.result[0].Status;
 devicename = myArr.result[0].Name;
 // myFunction(myArr);
 document.getElementById(location).innerHTML='<span class="device">'+devicename+'</span>';
 }
 if (onoff == "On") {
 document.getElementById(location).style.background = "red";
 } 
 if (onoff == "Off") {
 document.getElementById(location).style.background = "grey";
 }
 if (onoff == "Open") {
 document.getElementById(location).style.background = "red";
 } 
 if (onoff == "Closed") {
 document.getElementById(location).style.background = "grey";
 }
 }
xmlhttp.open("GET", url, true);
xmlhttp.send();
}

function getalldevices(){
fLen = devicestodisplay.length;
for (i = 0; i < fLen; i++) {
 preparediv(devicestodisplay[i]);
 getdevice(devicestodisplay[i]);
 }
}

function preparediv(deviceidx){
nod=nod+1;
var div = document.createElement("div");
div.className = 'devicecontainer';
div.id = "DEVICE"+deviceidx;
document.getElementById("devicesdiv").appendChild(div);
}

function updatealldevices(){
fLen = devicestodisplay.length;
for (i = 0; i < fLen; i++) {
 updatedevice(devicestodisplay[i]);
 }
}

function getdevice(idx){
 console.log("getting device idx" + idx);
 var xmlhttp = new XMLHttpRequest();
 var url = "http://"+domoticzurl+":"+domoticzport+"/json.htm?type=devices&rid="+idx;
 xmlhttp.onreadystatechange = function() {
 console.log(devicestodisplay[i] + " " +xmlhttp.readyState)
 if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
 var myArr = JSON.parse(xmlhttp.responseText);
 devicename = myArr.result[0].Name;
 devicestatus = myArr.result[0].Status;
 console.log(devicename + "(" + devicestatus+")");
 adddevice(idx,devicename,devicestatus);
 }
 }
xmlhttp.open("GET", url, true);
xmlhttp.send();
}

function adddevice(deviceidx,devicenametext,devicestatus){
nod=nod+1;
var div = document.createElement("div");
//div.style.width = "100px";
//div.style.height = "100px";
//div.style.background = "red";
//div.style.color = "white";
div.className = 'devicecontainer';
div.innerHTML = devicenametext;
div.id = "DEVICE"+deviceidx;

if (devicestatus=="On"){
 div.style.background = "red";
}

if (devicestatus=="Open"){
 div.style.background = "red";
}

if (devicestatus=="Off"){
 div.style.background = "grey";
}

if (devicestatus=="Closed"){
 div.style.background = "grey";
}

console.log("-------------"+div.id);
//document.getElementById("devicesdiv").appendChild(div);
document.getElementById(div.id).addEventListener('click', function() {
 { toggle(deviceidx); };
}, false);
}

function myFunction(arr) {
 var out = "";
 out += arr[0].result.Status;
 document.getElementById("id01").innerHTML = out;
}

//-->
</script>


<body>

<audio id="scene" src="assets/sounds/beep2.mp3" preload="auto"></audio>
<div align="left" class="toplinks">
<a href="index.htm"><span class="menutext">Home</span></a>
<a href="lights.htm"><span class="menutext">Lights</span></a>
<a href="devices.htm"><span class="menutext">Devices</span></a>
<a href="audiotrial.htm"><span class="menutext">Audio</span></a>
<a href="climate.htm"><span class="menutext">Environment</span></a>
<a href="security.htm"><span class="menutext">Security</span></a>
<a href="activities.htm"><span class="menutext">Other screens</span></a></div>
<div id="notification" align="center" class="notificationpane" onClick="clearnotification(11);"></div>
<div id="devicesdiv"></div>
</body>
</html>

Here’s the landscape.css file


body {
background-color:#000000;
font-family: 'Comfortaa', sans-serif;
margin: 0 0 0 0;
padding: 0 0 0 0 ;
}

.back-to-top {
background: none;
margin: 0;
position: fixed;
bottom: 50px;
right: 20px;
width: 150px;
height: 50px;
z-index: 100;
display: none;
text-decoration: none;
}

.back-to-top i {
font-size: 60px;
}

.timerselecttext {
font-size: 60px;
color:#FFFFFF;
}

.clockdisplay {
font-size: 250px;
color:grey;
}

div.clocktext {
font-size: 100px;
color:#000000;
}

div.weathertext {
font-size: 70px;
color:#000000;
}


div.standardcontainer {
background-color:grey;
position:relative;
width:25%;
height:25vh;
float:left;
padding-top:10px;
overflow:auto;
color:white;
font-size: 4vw;
text-align:center;
box-shadow:inset 0px 0px 0px 1px black;
}

div.doublecontainer {
background-color:grey;
position:relative;
width:50%;
height:25vh;
float:left;
padding-top:10px;
overflow:auto;
color:white;
font-size: 4vw;
text-align:center;
box-shadow:inset 0px 0px 0px 1px black;
}

div.devicecontainer {
background-color:grey;
width:25%;
height:12vh;
float:left;
padding-top:10px;
overflow:auto;
color:white;
font-size: 2vw;
box-shadow:inset 0px 0px 0px 1px black;
}


div.albumcontainer {
width:28vw;
height:28vw;
float:left;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.trackcontainer {
width:70vw;
height:10vw;
float:left;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.audiocontrols {
background-color:grey;
width:100vw;
height:10vw;
float:left;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.audioactivitycontainer {

width:70vw;
height:10vw;
float:left;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.camera {
background-color:grey;
width:100vw;
float:left;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.camcontrols {
background-color:green;
width:300px;
float:right;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

span {
background-color: #ffffff;
color: #75099b;
font-size:20px;
display: inline-block;
padding: 3px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

div.nightclock {
background-color:#333333;
position:relative;
width:100%;
float:left;
padding-top:10px;
overflow:auto;
color:#666666;
font-size: 5vw;
text-align:center;
box-shadow:inset 0px 0px 0px 1px black;
}

span.title {
background-color:#666666;
color:#FFFFFF;
font-size:35px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.timertext {
background-color:green;
color:#FFFFFF;
font-size:70px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.playstate {
background-color:green;
color:#FFFFFF;
font-size:12px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.temptext {
background-color:green;
color:#FFFFFF;
font-size:40px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.roomname {
background-color:green;
color:#FFFFFF;
font-size:40px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.lightroom {
background-color:green;
color:#FFFFFF;
font-size:30px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}


span.device {
background-color:#666666;
color:#FFFFFF;
font-size:20px;
display: inline-block;
padding: 3px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.sensor {
background-color:#666666;
color:#FFFFFF;
font-size:18px;
display: inline-block;
padding: 3px 10px;
margin: 0px 5px;
font-weight: bold;
border-radius: 5px;
}


span.screentitle {
background-color:#666666;
font-family: 'Baloo', sans-serif;
color:#FFFFFF;
font-size:30px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
border-radius: 5px;
}

span.menutext {
background-color:#0066FF;
color:#FFFFFF;
font-size:24px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.datetime {
background-color:#009900;
color:#FFFFFF;
font-size:16px;
display: inline-block;
padding: 5px 5px;
margin: 0px 5px;
border-radius: 5px;
}


div.audioroomcontainer {
background-color:#66FF99;
float:left;
height:200px;
padding-top:10px;
overflow:auto;
font-size: 25px;
margin: 0 0 10px 10px;
}

div.nightmodecontainer {
background-color:#666666;
width:150px;
float:left;
height:200px;
padding-top:10px;
overflow:auto;
font-size: 25px;
margin: 0 0 10px 10px;
}


div.notificationpane {
background-color:#FFFFCC;
width:100%;
font-size: 2.5vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.nightnotificationpane {
background-color:grey;
width:100%;
font-size: 2.5vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.toplinks {
background-color:#66CCFF;
top:0px;
left:0px;
width:100%;
font-size: 30px;
box-shadow:inset 0px 0px 0px 1px black;
}

div.popuppanel {
background-color:grey;
width:100vw;
float:left;
padding-top:10px;
overflow:auto;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

and here’s the portrait.css file


body {
background-color:#000000;
font-family: 'Comfortaa', sans-serif;
margin: 0 0 0 0;
padding: 0 0 0 0 ;
}

.back-to-top {
background: none;
margin: 0;
position: fixed;
bottom: 50px;
right: 20px;
width: 150px;
height: 50px;
z-index: 100;
display: none;
text-decoration: none;
}

.back-to-top i {
font-size: 60px;
}

.timerselecttext {
font-size: 60px;
color:#FFFFFF;
}

.clockdisplay {
font-size: 200px;
color:#000000;
}

div.clocktext {
font-size: 100px;
color:#000000;
}

div.weathertext {
font-size: 70px;
color:#000000;
}


div.nightclock {
background-color:#333333;
position:relative;
width:100%;
float:left;
padding-top:10px;
overflow:auto;
color:#666666;
font-size: 5vw;
text-align:center;
box-shadow:inset 0px 0px 0px 1px black;
}

div.doublecontainer {
background-color:grey;
position:relative;
width:100%;
height:25vh;
float:left;
padding-top:10px;
overflow:auto;
color:white;
font-size: 4vw;
text-align:center;
box-shadow:inset 0px 0px 0px 1px black;
}

div.standardcontainer {
background-color:grey;
position:relative;
width:50%;
height:15vh;
float:left;
padding-top:10px;
overflow:auto;
color:white;
font-size: 2vw;
text-align:center;
box-shadow:inset 0px 0px 0px 1px black;
}

div.nightclock {
background-color:#333333;
position:relative;
width:100%;
float:left;
padding-top:10px;
overflow:auto;
color:#666666;
font-size: 5vw;
text-align:center;
box-shadow:inset 0px 0px 0px 1px black;
}

div.devicecontainer {
background-color:grey;
width:50%;
height:10vh;
float:left;
padding-top:10px;
overflow:auto;
color:white;
font-size: 2vw;
box-shadow:inset 0px 0px 0px 1px black;
}


div.albumcontainer {
background-color:grey;
width:100vw;
height:100vw;
float:left;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.trackcontainer {
background-color:grey;
width:100vw;
float:left;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.audiocontrols {
background-color:grey;
width:100vw;
float:left;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.audioactivitycontainer {
background-color:grey;
width:100vw;
float:left;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.camera {
background-color:grey;
width:100vw;
float:left;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

div.camcontrols {
background-color:green;
width:100vw;
float:right;
padding-top:0px;
color:white;
font-size: 3vw;
box-shadow:inset 0px 0px 0px 1px black;
}

span.menutext {
background-color: #ffffff;
color: #75099b;
font-size:3vw;
display: inline-block;
padding: 3px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span {
background-color: #ffffff;
color: #75099b;
font-size:18px;
display: inline-block;
padding: 3px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.title {
background-color:#666666;
color:#FFFFFF;
font-size:18px;
display: inline-block;
padding: 3px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.timertext {
background-color:green;
color:#FFFFFF;
font-size:20px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.lightroom {
background-color:green;
color:#FFFFFF;
font-size:16px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}
span.temptext {
background-color:green;
color:#FFFFFF;
font-size:20px;
display: inline-block;
padding: 10px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}
span.device {
background-color:#666666;
color:#FFFFFF;
font-size:18px;
display: inline-block;
padding: 3px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.screentitle {
background-color:#666666;
font-family: 'Baloo', sans-serif;
color:#FFFFFF;
font-size:18px;
display: inline-block;
padding: 5px 5px;
margin: 5px;
border-radius: 5px;
}


span.menutext {
background-color:#0066FF;
color:#FFFFFF;
font-size:24px;
display: inline-block;
padding: 3px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.datetime {
background-color:#009900;
color:#FFFFFF;
font-size:12px;
display: inline-block;
padding: 5px 5px;
margin: 0px 5px;
border-radius: 5px;
}

span.sensor {
background-color:#666666;
color:#FFFFFF;
font-size:14px;
display: inline-block;
padding: 3px 10px;
margin: 0px 5px;
font-weight: bold;
border-radius: 5px;
}

div.audioroomcontainer {
background-color:#66FF99;
float:left;
height:200px;
padding-top:10px;
overflow:auto;
font-size: 25px;
margin: 0 0 10px 10px;
}

div.nightmodecontainer {
background-color:#666666;
width:150px;
float:left;
height:200px;
padding-top:10px;
overflow:auto;
font-size: 25px;
margin: 0 0 10px 10px;
}


div.notificationpane {
background-color:#FFFFCC;
width:100%;
font-size: 16px;
box-shadow:inset 0px 0px 0px 1px black;
}


div.toplinks {
background-color:#66CCFF;
top:0px;
left:0px;
width:100%;
font-size: 30px;
overflow:scroll;
box-shadow:inset 0px 0px 0px 1px black;
}

div.popuppanel {
background-color:grey;
width:100vw;
float:left;
padding-top:10px;
overflow:auto;
color:white;
font-size: 2vw;
box-shadow:inset 0px 0px 0px 1px black;
}

Creating a custom HTML front end for Domoticz part 2 – YouTube companion article

This article just shows the code that accompanies the next in the multi-part series explaining how I created my (reasonably popular!) HTML front end.

The icon I used can be downloaded from Flaticon.com but remember to download two versions, one you should rename dehumidifier-on.png and one dehumidifier-off.png

Here’s the code.

index.htm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<head>
<title>Home Control</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
		<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
		<meta name="apple-mobile-web-app-capable" content="yes" />
		<meta name="mobile-web-app-capable" content="yes" />
		<meta name="apple-mobile-web-app-status-bar-style" content="black" />

		<meta http-equiv="content-type" content="text/html; charset=utf-8" />
		<meta name="description" content="" />
		<meta name="keywords" content="" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
			<link rel="shortcut icon" href="favicon.ico" />
			<link rel="apple-touch-icon" href="iphone-icon.png"/>
			<link rel="icon" sizes="196x196" href="logo.png">
			<link rel="icon" sizes="192x192" href="logo192.png">
			<link rel="stylesheet" media="(orientation: portrait)" href="portrait.css">
			<link rel="stylesheet" media="(orientation: landscape)" href="landscape.css">

  	<link href="https://fonts.googleapis.com/css?family=Baloo|Comfortaa" rel="stylesheet">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<script language="JavaScript" type="text/JavaScript">

var domoticzurl="192.168.1.163"

function MM_goToURL() { //v3.0
  var i, args=MM_goToURL.arguments; document.MM_returnValue = false;
  for (i=0; i<(args.length-1); i+=2) eval(args[i]+".location='"+args[i+1]+"'");
}
function speak(textToSpeak) {
   // Create a new instance of SpeechSynthesisUtterance
   var newUtterance = new SpeechSynthesisUtterance();

   // Set the text
   newUtterance.text = textToSpeak;

   // Add this text to the utterance queue
   window.speechSynthesis.speak(newUtterance);
}

function switchon(devicecode){
	execute('PUT', 'http://' + domoticzurl + ':8080/json.htm?type=command&param=switchlight&idx='+devicecode+'&switchcmd=On', '');
}

function switchoff(devicecode){
	execute('PUT', 'http://' + domoticzurl + ':8080/json.htm?type=command&param=switchlight&idx='+devicecode+'&switchcmd=Off', '');
}

function toggle(devicecode){
	execute('PUT', 'http://' + domoticzurl + ':8080/json.htm?type=command&param=switchlight&idx='+devicecode+'&switchcmd=Toggle', '');
}

function dim(devicecode,dimlevel){
	execute('PUT', 'http://' + domoticzurl + ':8080/json.htm?type=command&param=switchlight&idx='+devicecode+'&switchcmd=Set%20Level&level='+dimlevel, '');
}


function execute($method,$url,$message){
xmlhttp=new XMLHttpRequest();
xmlhttp.open($method,$url,true)
xmlhttp.send($message);
}

function toggleDiv(divId) {
   $("#"+divId).toggle(100);
}

function hideDiv(divId) {
   $("#"+divId).hide();
}
	
window.addEventListener("load", function(){
});;

function hideallDivs() {
    hideDiv("lights");
	hideDiv("devices");
}

//the following functions will run every second (due to the 1000 at the end).
window.setInterval(function(){
	updatedevice(36,'dehumidifier',"dehumidifier-on.png","dehumidifier-off.png");
	}, 1000);


// the following function checks to see if the idx is "on" or "off" and updates the image accordingly
function updatedevice(idx,location,onimage,offimage){
	console.log("checking status of idx "+idx);
	var xmlhttp = new XMLHttpRequest();
	var url = "http://"+domoticzurl+":8080/json.htm?type=devices&rid="+idx;
	var onoff;
	xmlhttp.onreadystatechange = function() {
    	if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        	var myArr = JSON.parse(xmlhttp.responseText);
			onoff = myArr.result[0].Status;
       // myFunction(myArr);
    	}
		if (onoff == "On") {
		document.getElementById(location).src = onimage;
		} 
		if (onoff == "Off") {
		document.getElementById(location).src = offimage;
		}
		if (onoff == "Open") {
		document.getElementById(location).src = onimage;
		} 
		if (onoff == "Closed") {
		document.getElementById(location).src = offimage;
		}
	}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}


</script>

</head>

<body>

<a href="javascript:;"  onclick="toggleDiv('lights');"><span class="navtitle">Lights</span></a>
<div id="lights" class="navlights">
Desk Lamp

<a href="javascript:;" onclick="dim(594,16);toggleDiv('lights');"><span class="buttontext">Max</span></a>
<a href="javascript:;" onclick="dim(594,12);toggleDiv('lights');"><span class="buttontext">75%</span></a>
<a href="javascript:;" onclick="dim(594,8);toggleDiv('lights');"><span class="buttontext">50%</span></a>
<a href="javascript:;" onclick="dim(594,4);toggleDiv('lights');"><span class="buttontext">25%</span></a>
<a href="javascript:;" onclick="switchoff(594);toggleDiv('lights');"><span class="buttontext">Off</span></a>

<hr width="90%" style="dashed" color="#FFFFFF" size="2">

Ceiling Lamp

<a href="javascript:;" onclick="dim(81,100);toggleDiv('lights');"><span class="buttontext">Max</span></a>
<a href="javascript:;" onclick="dim(81,75);toggleDiv('lights');"><span class="buttontext">75%</span></a>
<a href="javascript:;" onclick="dim(81,50);toggleDiv('lights');"><span class="buttontext">50%</span></a>
<a href="javascript:;" onclick="dim(81,25);toggleDiv('lights');"><span class="buttontext">25%</span></a>
<a href="javascript:;" onclick="switchoff(81);toggleDiv('lights');"><span class="buttontext">Off</span></a></div>
<a href="javascript:;"  onclick="toggleDiv('devices');"><span class="navtitle">Devices</span></a>
<div id="devices" class="navlights">
Dehumidifier

<a href="javascript:;" onclick="toggle(36);"><img id="dehumidifier" src="dehumidifier-off.png"></a></div>
</body>

And here are the 2 css sheets you need (I don’t know why I have done this yet but these will be useful when we start looking at device orientation.

Portrait.css

html {
margin: 0;
padding: 0;
}
body {
margin: 0;
padding: 0;
background-color:#000000;
}
div.navlights {
display:block;
text-align:center;
position:relative;
width: 100vw;
margin:0vw;
background-color:#CCCCCC;
font-family: 'Comfortaa', cursive;
font-size:6vw;
font-color:#000000;
}
span.buttontext {
background-color: #ffffff;
color: #75099b;
font-size:6vw;
display: inline-block;
padding: 3px 10px;
margin: 1vw;
font-weight: bold;
border-radius: 5px;
}

span.toggletext {
background-color: #FF66CC;
color:#ffffff;
font-size:6vw;
display: inline-block;
padding: 3px 10px;
margin: 1vw;
font-weight: bold;
border-radius: 5px;
}

span.navtitle {
color: #FFFFFF;
font-size:5vw;
display: inline-block;
margin: 3vw;
font-family: 'Baloo',cursive;
font-weight: normal;
}

landscape.css

html {
margin: 0;
padding: 0;
}
body {
margin: 0;
padding: 0;
background-color:#000000;
}
div.navlights {
display:block;
text-align:center;
position:relative;
width: 100vw;
margin:0vw;
background-color:#CCCCCC;
font-family: 'Comfortaa', cursive;
font-size:40px;
font-color:#000000;
}
span.buttontext {
background-color: #ffffff;
color: #75099b;
font-size:36px;
display: inline-block;
padding: 3px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.toggletext {
background-color: #FF66CC;
color:#ffffff;
font-size:36px;
display: inline-block;
padding: 3px 10px;
margin: 5px;
font-weight: bold;
border-radius: 5px;
}

span.navtitle {
color: #FFFFFF;
font-size:50px;
display: inline-block;
margin: 5px;
font-family: 'Baloo',cursive;
font-weight: normal;
}