1.05 A quick WebApp for your thermostat

If you have done your thermostat following my previous posts you have are to make a quick WebApp for control your stove from smartphone.

Initialy you have to know that this WebApp is avaiable only on your LAN, your private network. Obviously you have a WIFI in your home, right?

My beautiful web-app that control lights, stove, doorbell ecc

You have yet the /var/www/html path. Since now, I will call this path the wwwroot, ok? On wwwroot you have yet the /include/ path and /script/ path. You have to create /css/, /images/, and /js/

Jquery and jQuery mobile

we prepare the JS path. I love to use JQuery, but not in CDN…. because is dangerous… if you lost internet you can’t control your thermostat. You have to download ALL JQUERY files…. and put them into /js/.

I have the 1.11 minified. Go here and download https://code.jquery.com/jquery/

I use the JqueryMobile platform for making a very beautiful WebApp. You can download all files (js, css, images ecc) here https://jquerymobile.com/download/

Manifest.json for Android Web App

Android permit you to create a splendid WebApp that shows like a very Installed App. You have to configure a file named manifest.json. The complete guide is here https://developers.google.com/web/fundamentals/web-app-manifest/.

edit manifest.json for create a webapp
edit manifest.json for create a webapp

This permit you to add this website to Desktop, and see this like an APP.

This file is located in wwwroot, and this is the code

{
   "manifest_version": 2,
   "version": "0.1",
   "name": "Silvano",
   "icons": [
   {
      "src": "images/ico.png",
      "sizes": "128x128",
      "type": "image/png"
   }
   ],
   "start_url": ".",
   "display": "standalone",
   "orientation": "portrait" 
}

Index.php

The index.php is a container for other pages. A simple menu with the hamburger present a link for the HOME and stop. In future we will add other pages. Here is the code

<?php include("include/init.php");
$page=$_GET["page"];
if( !file_exists($page.".php") ) $page="home";

?>

<!DOCTYPE html> 
<html> 
<meta charset="utf-8" />
<head> 
<title>YourName</title> 
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"> 
<meta name="mobile-web-app-capable" content="yes">
<link rel="manifest" href="manifest.json">
<meta name="theme-color" content="#db5945">

<script src="js/jquery-1.11.1.min.js"></script>
<script src="js/jquery.mobile.custom.min.js" type="text/javascript"></script>
<link href="css/jquery.mobile.custom.theme.min.css" rel="stylesheet" type="text/css">
<link href="css/jquery.mobile.custom.structure.min.css" rel="stylesheet" type="text/css">
<link href="css/themes/default/jquery.mobile-1.4.5.min.css" rel="stylesheet" type="text/css">
<script src="js/jquery.maphilight.min.js" type="text/javascript" ></script>
<script src="js/varie.js"></script>

<script language="javascript">
$(document).ready(function(){
    var window_w=$(window).width()-10;
    var mid=(window_w-200)/2;

$("#loading").css("padding-top",$(window).height()/2-40);

$( "#mymenu" ).panel();
$( "#mymenu ul" ).listview();

$( document ).on( "swiperight", function( e ) {
$('#mymenu').panel('open');
});


});


</script>
<style>
#loading
{
position:fixed;
left:0px; 
top:0px; 
width:100%;
z-index:-1000;
height:100%;
background-color:black;
opacity:0.6;
font-weight:bold;
text-align:center;
font-size:16px;
color:white;

}
body {
padding-bottom: 20px;
}
</style>
</head>
<body>

<div data-role="page">
<div data-role="header" data-tap-toggle="false" data-theme="b">

<img src="images/hamburger.png" class="ui-btn-left" onClick="$('#mymenu').panel('open');"/>
<h1>Silvano</h1>
</div>

<?php include($page.".php") ?>

<div id="loading"><img src="images/ajax-loader.gif" /><br>Caricamento...</div>

</div>

<div data-role="panel" id="mymenu" data-position="left" data-display="push" data-theme="b">
<center><h3>Silvano</h3>
<ul data-role="ul_menu">

<li data-icon="home"><a href="?page=home" onClick="loading(true)" rel="external"><h2>Home</h2></a></li>
</ul>

<div style="clear:both"></div>
</div>


</body>
</html>

API for your stove

Yes, my stove has an API. And if you are here…. maybe also your stove has as API. I created into wwwroot, a path called /api/temperature/ and in it, a file called index.php. In this code I use function that we seen in previous post for example threshold() seen here…

Here is the code of /var/www/html/api/temperature/index.php

<?php include(__DIR__."/../../include/init.php");

if( $_GET["op"]=="set" )
{
   if( isset($_GET["threshold0"]) )
      soglia(0,round($_GET["threshold0"],1));

   if( isset($_GET["threshold0_move"]) )
      threshold(0,threshold(0)+$_GET["threshold0_move"]);

   //******

   if( isset($_GET["threshold1"]) )
      threshold(1,round($_GET["threshold1"],1));

   if( isset($_GET["threshold1_move"]) )
      threshold(1,threshold(1)+$_GET["threshold1_move"]);

   $json=array("done"=>1);
}
   else
{
   $json=array( "timestamp"=>time(),

   "tZ"=>round(gpio_read_temp(TEMP_Z),1),
   "t0"=>round(gpio_read_temp(TEMP_F0),1),
   "t0_threshold"=>threshold(0),
   "t1"=>round(gpio_read_temp(TEMP_F1),1),
   "t1_threshold"=>threshold(1),
);

   //relais are active_low, I will invert
   $json["stove"]=(gpio_read(PIN_RELAY_STOVE)==0 ? 1 : 0);

   if( $json["stove"]==0 )
      $json["f0"]=$json["f1"]=0;
   else
   {
      $json["f0"]=(gpio_read(PIN_SOLENOIDVALVE_0)==0 ? 1 : 0);
      $json["f1"]=(gpio_read(PIN_SOLENOIDVALVE_1)==0 ? 1 : 0);
   }
}

$json=json_encode($json,JSON_PRETTY_PRINT);

ob_clean();
echo $json;
die();

?>

home.php

The HOME is the first page where you can monitor and switch on and off your stove. We will use short pooling AJAX for monitor all data.

<style>
.t
{ 
   position:absolute;
   text-align:center;
   font-weight:bold;
}
.tZ
{
   font-size:70px;
   color:white;
   width:100%;
   left:0px;
   top:0px;
   text-shadow: 0px 3px 5px rgba(0, 0, 0, 0.40),0px -3px 5px rgba(0, 0, 0, 0.40),3px 0px 5px rgba(0, 0, 0, 0.40),-3px 0px 5px rgba(0, 0, 0, 0.40);
}
.t0
{
   font-size:55px;
   color:white;
   padding-top:20px;
   width:130px;
   height:110px;
   border-radius:50%;
   left:20px;
   top:0px;
   background-color:#ff3636;
   background-image:url(images/frecce_overlay.png);
   box-shadow:0px 0px 1px black;
   text-shadow:none !important;
}
.t0 div
{
   margin-left:20px;
}
.t1
{
   font-size:55px;
   color:white;
   padding-top:20px;
   width:130px;
   height:110px;
   border-radius:50%;
   left: 150px; 
   top:0px;
   background-color:#9a9a9a;
   background-image:url(images/frecce_overlay.png);
   box-shadow:0px 0px 1px black;
   text-shadow:none !important;
}
#changeT0, #changeT1
{
   position:absolute; 
   left:0px; 
   top:0px; 
   border:0px solid black; 
   z-index:999; 
   width:130px; 
   height:130px;
}
</style>
<script language="javascript">
var do_something=false;
var soglie = [0,0];

$(document).ready(function(){
   $("body").hide();
   setTimeout(design,100);
});

function design()
{
   loading(true);
   var h=$(window).height();
   var w=$(window).width();

   var myh=0.40;

   $(".t1").css("left",w-150);
   $(".tZ").css("top",h*.10);
   $(".t0").css("top",h*0.50);

   $(".t1").css("top",h*0.50);

   var top=$("#t0").css("top");
   var left=$("#t0").css("left");
   $("#changeT0").css("top",top);
   $("#changeT0").css("left",left);

   var top=$("#t1").css("top");
   var left=$("#t1").css("left");
   $("#changeT1").css("top",top);
   $("#changeT1").css("left",left);

   getTemp();

   $("body").show();
}

function getTemp()
{
   var url="api/temperature/";
   $.getJSON(url,function(json){
      $("#tZ .intPart").html( integerPart(json.tZ)+"&deg;");
      $("#tZ .decPart").html( "."+decimalPart(json.tZ));

      soglie[0]=json.t0_soglia;
      $("#t0 .intPart").html( integerPart(json.t0)+"&deg;");
      $("#t0 .decPart").html( "."+decimalPart(json.t0));
      $("#t0 .soglia").html( integerPart(json.t0_soglia)+"."+decimalPart(json.t0_soglia)+"&deg;");

      soglie[1]=json.t1_soglia;
      $("#t1 .intPart").html( integerPart(json.t1)+"&deg;");
      $("#t1 .decPart").html( "."+decimalPart(json.t1));
      $("#t1 .soglia").html( integerPart(json.t1_soglia)+"."+decimalPart(json.t1_soglia)+"&deg;");

      //************
      if( json.p0==0 )
         $("#t0").css("background-color","#9a9a9a");
      else
         $("#t0").css("background-color","#ff3636");

      //************
      if( json.p1==0 )
         $("#t1").css("background-color","#9a9a9a");
      else
         $("#t1").css("background-color","#ff3636");
      //*************
   }
   setTimeout(getTemp,5000);
});
}

function muovi_soglia(npiano,delta)
{
   var url="api/temperature/?op=set&soglia"+npiano+"_muovi="+delta;

   soglie[npiano]+=delta;
   $("#t"+npiano+" .soglia").html( "**"+integerPart(soglie[npiano])+"."+decimalPart(soglie[npiano])+"&deg;");

   $.getJSON(url,function(json){
   });

}

</script>
<div data-role="content" style="padding:0px;">

<img id="changeT0" usemap="#map_soglia_0" src="images/trasparent.png" />
<img id="changeT1" usemap="#map_soglia_1" src="images/trasparent.png" />

<div class="t t0" id="t0">
<span class="intPart" style="margin-left:0px">&nbsp;</span>
<span class="decPart" style="font-size:40%; margin-left:-40px">&nbsp;</span>
<div class="soglia" style="font-size:20px; margin-top:-13px; margin-left:0px">&nbsp;</div>
</div>

<div class="t t1" id="t1">
<span class="intPart" style="margin-left:0px">&nbsp;</span>
<span class="decPart" style="font-size:40%; margin-left:-40px">&nbsp;</span>
<div class="soglia" style="font-size:20px; margin-top:-13px; margin-left:0px">&nbsp;</div>
</div>

<div style="clear:both"></div>

<map name="map_soglia_0">
<area shape="rect" coords="0,0,130,65" href="javascript:void(0)" onClick="muovi_soglia(0,+0.5)">
<area shape="rect" coords="0,65,130,130" href="javascript:void(0)" onClick="muovi_soglia(0,-0.5)">
</map>
<map name="map_soglia_1">
<area shape="rect" coords="0,0,130,65" href="javascript:void(0)" onClick="muovi_soglia(1,+0.5)">
<area shape="rect" coords="0,65,130,130" href="javascript:void(0)" onClick="muovi_soglia(1,-0.5)">
</map>
<div style="clear:both"></div>

</div>

BeAware! Errors in my code!

My code in reality is more complex than this…. please don’t expect that this code running without errors or corrections…. my goal is only offer to you some tips 🙂

By the way…. this is my beauty web-app

Please follow and like us:

Leave a Reply

Your email address will not be published. Required fields are marked *

Fork me on GitHub