Raspberry button trigger Python script which should display in webpage - javascript

I have a Raspberry PI with a button attached to it.
I run a Python script on it to detect when the button is pressed.
When the button is pressed, it increment a number in a text file.
I need to display this number on a web page (Apache) and to launch a sound.
For the moment, my python script change the index.html with the value I need and I am using <meta http-equiv="refresh" content="1"> to resfresh the page.
The problem is that I need to know when the number is changing to launch the sound.

Too little information to say something concrete, but here's how I'd get around to it given the main following limitation that the page is not dynamic (no ajax).
General outline:
Put the value from the text file in a identifiable field like
<span id="myNumber">#the number from file goes here </span>
then on load with java script read the value of the field:
(planin JS)
var myNumberValue = document.getElementById('myNumber').innerHTML;
then create a cookie to store the last value on clinets machine:
document.cookie = "lastNumber="+myNumberValue;
To sum it all up: on loading the webpage launch a script that will :
check for a cookie
read a value from the coookie
(http://www.w3schools.com/js/js_cookies.asp)
read a value from the field
if a cookie exists compare the values and if the number
changed play a sound like here:
Playing audio with Javascript?
either way store the value from the field to the cookie for next
website update.
[Edit] Full working solution using local storage or cookies:
<html>
<head>
<META HTTP-EQUIV="refresh" CONTENT="5">
<script type="text/JavaScript">
function myFunction()
{
var numberDisplayed = parseInt(document.getElementById('myNumber').innerHTML);
var numberInCookie = numberDisplayed;
//lets assume that's the only data in the cookie
var tmpData = readNumber();
if(tmpData!="NaN" && tmpData!= "undefined")
{
numberInCookie = tmpData;
}
if(numberDisplayed!=numberInCookie)
{
alert("changed to from "+ numberInCookie+" to " + numberDisplayed);
}
saveNumber(numberDisplayed);
}
function readNumber()
{
if (typeof(Storage) !== "undefined") {
return localStorage.getItem("lastNumber")
} else {
var cookieData = document.cookie;
//lets assume that's the only data in the cookie
var tmpData = parseInt(cookieData.split("=")[1]);
return tmpData
}
}
function saveNumber(number)
{
if (typeof(Storage) !== "undefined") {
localStorage.setItem("lastNumber", number);
} else {
document.cookie = "lastNumber="+number;
}
}
</script>
</head>
<body onload="myFunction()">
<span id="myNumber">2</span>
</body>
</html>
[Edit 2] as the author of the question hinted he doesn't actually want to use the site refresh here's another option:
lest start a loop that will load a test file from the server as an ajax request. then the data is loaded, parsed, store it loacally as before. and set timer to trigger the refresh again.
One importatnt thing the files need to be available on the same domain / server (see HTTP access control (CORS) for more information)
<html>
<head>
<script type="text/JavaScript">
var externalNumber = 0;
var timer;
function myFunction()
{
// start the readouts:
LoadExternalData();
}
function LoadExternalData()
{
var client = new XMLHttpRequest();
client.open("GET", "http:/myserver/readme.txt");
client.onreadystatechange = function() {
externalNumber = parseInt(responseText);
//store a local copy
var NewestNumber = externalNumber;
var tmpData = readNumber();
if(tmpData!="NaN" && tmpData!= "undefined")
{
numberInCookie = tmpData;
}
if(NewestNumber!=numberInCookie)
{
alert("changed to from current "+ numberInCookie+" to " + NewestNumber);
}
saveNumber(NewestNumber);
timer = setTimeout(LoadExternalData, 1000);
}
client.send();
}
function readNumber()
{
if (typeof(Storage) !== "undefined") {
return localStorage.getItem("lastNumber")
} else {
var cookieData = document.cookie;
//lets assume that is the only data in the cookie
var tmpData = parseInt(cookieData.split("=")[1]);
return tmpData
}
}
function saveNumber(number)
{
if (typeof(Storage) !== "undefined") {
localStorage.setItem("lastNumber", number);
} else {
document.cookie = "lastNumber="+number;
}
}
</script>
</head>
<body onload="myFunction()">
<span id="myNumber">2</span>
</body>
</html>

Related

App Script - Open Url in new Tab from Google WebApp (without assigned Spreadsheet)

I want to create a WebApp, that does the following:
User clicks button on WebApp to run script
Get User eMail
Create new Google Spreadsheet (name=eMail)
get Url of that Spreadsheet
Automatically open Url in new Tab
Step 5 is where I am stuck.
I have used window.open(url) before, however that only seems to work when you run code via a Spreadsheet. What I wanna do is displaying the button on my .html and run everything only with the WebApp but I can't do that because I can not use SpreadsheetApp.getUi() from that context.
Is there another way to do this?
Here is the Error im getting:
EDIT: Seems I had some minor mistakes in my Code.gs I think i fixed that now. Still same issue tho
Thank you guys in advance! :)
Here is some sample code:
Code.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile("page");
}
function clickEvent () {
const lock = LockService.getScriptLock();
lock.tryLock(5000);
if (lock.hasLock()){
var email = Session.getActiveUser().getEmail();
var url = createFile(email);
openUrl(url); //THIS ONLY WORKED FROM WITHIN SPREADSHEET
lock.releaseLock();
}
}
function createFile(email){
var newSS= SpreadsheetApp.create(email);
var file = DriveApp.getFileById(newSS.getId());
var url = file.getUrl();
return url
}
function openUrl( url ){ //HAS TO CHANGE
var html = HtmlService.createHtmlOutput('<html><script>'
+'window.close = function(){window.setTimeout(function(){google.script.host.close()},9)};'
+'var a = document.createElement("a"); a.href="'+url+'"; a.target="_blank";'
+'if(document.createEvent){'
+' var event=document.createEvent("MouseEvents");'
+' if(navigator.userAgent.toLowerCase().indexOf("firefox")>-1){window.document.body.append(a)}'
+' event.initEvent("click",true,true); a.dispatchEvent(event);'
+'}else{ a.click() }'
+'close();'
+'</script>'
// Offer URL as clickable link in case above code fails.
+'<body style="word-break:break-word;font-family:sans-serif;">Failed to open automatically. Click here to proceed.</body>'
+'<script>google.script.host.setHeight(40);google.script.host.setWidth(410)</script>'
+'</html>')
.setWidth( 90 ).setHeight( 1 );
SpreadsheetApp.getUi().showModalDialog( html, "Opening ..." );
}
}
page.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Click Button!</h1>
<button id="btn">Run</button>
<script>
document.getElementById("btn").addEventListener("click",sendRequest);
function sendRequest(){
google.script.run.clickEvent();
}
</script>
</body>
</html>
Get url from app script and open spreadsheet in new tab wit JavaScript
Update app script function
function clickEvent () {
const lock = LockService.getScriptLock();
lock.tryLock(5000);
if (lock.hasLock()){
var email = Session.getActiveUser().getEmail();
lock.releaseLock();
return createFile(email);
}
}
Also update JavaScript Code
function sendRequest(){
google.script.run.withSuccessHandler(
function (link) {
window.open(link, '_blank').focus();
}
).testCSV3();
}
Reference: Communicate with Server Functions

Get Variable Value from inside code.gs Google App Script to Javascript

I have a simple webapp that show a button and when a user clicked, it will open a new window that shows a website. What I want to do is when a user clicked the button, it will get the value from my google sheet and open a new window based on that value. Then, the webapp will update the value in the google sheet with a new value.
For example:
if the value in my google sheet is "Google", it will open a window to "www.google.com" and then update the google sheet value to "other website".
I have succesfully made the function for updating the value on google sheet whenever a user clicked the button but I fail in getting the value from the code.gs/google sheet to my Javascript.
Please help.
here is my code.gs:
var url = "url"; //mygooglesheet url
var web = "";
function doGet(e) {
let tmp = HtmlService.createTemplateFromFile("index");
return tmp.evaluate();
}
function setWebsite () {
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("website");
web = ws.getRange(1,1,1,1).getValue();
if (web === "Google") {
ws.getRange(1,1,1,1).setValue("Youtube");
}
else if (web === "Youtube") {
ws.getRange(1,1,1,1).setValue("Facebook");
}
else {
ws.getRange(1,1,1,1).setValue("Google");
}
}
function getWebsite() {
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("website");
var web = ws.getRange(1,1,1,1).getValue();
return web;
}
my index.html:
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Please Click Below</h1>
<!-- <h2><?=web?>:</h2> -->
<button id = "btn" type="submit" >Open Window</button>
<script>
document.getElementById("btn").addEventListener("click", doStuff);
var web = "";
function doStuff() {
google.script.run.getWebsite(); //dont know for sure if this is needed or not
google.script.run.setWebsite();
web = <?=web?>; //dont know for sure if this is needed or not
if (web === "Google") {
window.open("https://www.google.com/");
}
else if (web === "Youtube") {
window.open("https://www.youtube.com/");
}
else {
window.open("https://www.facebook.com/");
}
}
</script>
</body>
</html>
Right now, my webapp only open a new window to "facebook.com" and update to the next value in the code. I tried "google.script.run.withSuccessHandler(onSuccess).getWebsite()" but not successful to get the variable value from the code.gs, please help.
Thank you.
Issue:
You want to open a new tab with the URL returned by getWebsite() when the button is clicked.
Solution:
In order to handle data returned by a server-side function called by google.script.run, use the success handler. The function called by this handler will be passed the value returned by the server-side function (getWebsite()) as a parameter.
Code sample:
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Please Click Below</h1>
<button id = "btn" type="submit" >Open Window</button>
<script>
document.getElementById("btn").addEventListener("click", doStuff);
function doStuff() {
google.script.run.withSuccessHandler(openWebsite).getWebsite();
}
function openWebsite(web) {
if (web === "Google") {
window.open("https://www.google.com/");
} else if (web === "Youtube") {
window.open("https://www.youtube.com/");
} else {
window.open("https://www.facebook.com/");
}
}
</script>
</body>
</html>
Note:
If the data returned by getWebsite() is supposed to remain static between the moment in which the page first loads and when the button is clicked, you could also use the approach mentioned by Mike Steelson, using template scriplets.
In html, in script section, write
<? var web = getWebsite(); ?>
and erase google.script.run.getWebsite();

local storage items after refresh page

<!DOCTYPE html>
<html>
<body>
<button onclick="myFunction();">Fav Number</button>
<div id="result"></div>
<!--This code works on chrome-->
<script>
function myFunction() {
// Check browser support
if (typeof(Storage) !== "undefined") {
// Store
var a = prompt("fav number");
localStorage.setItem("lastname", a);
// Retrieve
document.getElementById("result").innerHTML = localStorage.getItem("lastname");
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support Web Storage...";
}
}
</script>
</body>
</html>
hello,
is it possible to get local storage items back when you refresh the page?
and if so, how?
Thanks
Dylan,
Getting and setting localStoragedata. In following example the data to set is a Object (which is handled by JSON.stringify). If need to persist a string / intthere is no need in using JSON.stringify.
var dataObject = { 'item1': 1, 'item2': 2, 'item3': 3 };
// Set localStorage item
localStorage.setItem('dataObject', JSON.stringify(dataObject));
// Retrieve the object from localStorage
var retrievedObject = localStorage.getItem('dataObject');
// console.log retrieved item
console.log('retrieved data Object: ', JSON.parse(retrievedObject));
By getting localStorage data when needed, there no need to handle the page refresh part. The localStorage data is fetched when needed by application functions and logics.

Using jQuery for setting Local Storage Keys from Input Value

So I'm trying to start on a to do list in html5 + jQuery using Local Storage, but for some odd reason I can't get the jQuery to make a local storage key.
Here is my code. I want it to collect the value of the input box, add it to local storage, and then print the code in the div named.
$('#taskEntryForm').submit(function () {
if ($('#taskInput').val() !== '') {
var input_value = $('#taskInput').val();
var stored_input = this.localStorage.setItem('task_',input_value);
var task = this.localStorage.getItem('task_');
$('#taskList').append("<br>"+task);
};
return false;
});
and then the HTML...
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="shit.js"></script>
</head>
<div id="cNew">
<form id="taskEntryForm">
<input id="taskInput" name="taskInput" autofocus></form>
</div>
<div id="taskList"></div>
</html>
In your code this stands for form. Local storage object is not part of the form, it is a part of window. You should change this (which represents form) to window, or remove this at all (because window.localStorage is identical to just localStorage):
$('#taskEntryForm').submit(function () {
if ($('#taskInput').val() !== '') {
var input_value = $('#taskInput').val();
var stored_input = localStorage.setItem('task_',input_value); // <- removed 'this'
var task = localStorage.getItem('task_'); // <- removed 'this'
$('#taskList').append("<br>"+task);
};
return false;
});
Here is a working jsFiddle

Posting form values securely from one page to another on client-side using pure Javascript and NO server-side technology

I need to POST form values from one page to another using Javascript.
Now, I know that I could use a server-side technology like ASP.Net or PHP to post values but I am not allowed to use any server side script.
I am aware that using the GET method, I can pass the form values as a query string but the values will not be passed securely (which is an important requirement!)
The conditions listed below:
This code should take the values that are posted to the page and
repost to target page. HTTP POST only (not get).
In no cases, even error, the request should not stop on this bridge page.
The script needs to handle multiple posted values.
Try to use standard javascript (no 3rd party library)
Script needs to work in IE, FF, Safari, most standard browsers
Can anyone please help me find a solution to this or point me to some resource that will help me find the soln? Thanks in advance. Below is the code for passing values as a query string. Can I modify this so that my above requirements are satisfied?
FORM
<html>
<head>
<title>Test</title>
<script type="text/javascript">
function goto_page(page) {
var usbnum = document.getElementById('usbnum').value;
var usbcode = document.getElementById('usbcode').value;
var q_str = '?usbnum=' + usbnum + '&usbcode=' + usbcode;
var url = page + q_str;
window.location = url;
}
</script>
</head>
<form id="form1" method="post">
<div>
USB No: <input name="usbnum" id="usbnum" type="text" size="80" /><br />
USB Code: <input name="usbcode" id="usbcode" type="text" size="80"/>
</div>
Next
</form>
</body>
</html>
BRIDGE PAGE
<html>
<head>
<title>Bridge Page</title>
<script type="text/javascript">
function get_params() {
var url = window.location.href;
var q_str_part = url.match(/\?(.+)$/)[1];
var val_pairs = q_str_part.split('&');
var params = {};
for (var i = 0; i < val_pairs.length; i++) {
var tmp = val_pairs[i].split('=');
params[tmp[0]] = typeof tmp[1] != 'undefined' ? tmp[1] : '';
}
return params;
}
function write_params() {
var params = get_params();
var txt = 'Hello ';
for (var i in params) {
txt += params[i] + ' ';
}
var body = document.getElementsByTagName('body')[0];
body.innerHTML += txt;
}
function write_params() {
var params = get_params();
var num_container = document.getElementById('usbnum');
var code_container = document.getElementById('usbcode');
num_container.innerHTML = params.usbnum;
code_container.innerHTML = params.usbcode;
}
</script>
</head>
<body onLoad="write_params()">
</body>
</html>
POST data can only be handled by server side code. There is no way you can use them in your javascript without help from a server side code.
You can only use GET or you can think about cookies. But at other hand, why do you want to change current page?! you can use AJAX to load more data without refreshing and no need of posting or getting variables.

Categories