sboerhoop
Posts: 3
Joined: Tue Mar 21, 2017 1:45 pm

button pressed > popup on webpage

Tue Mar 21, 2017 1:53 pm

I connected a button to pin 18 with a pullup resistor

When I press the button, I want to have a popup in a website page, what reflects a text... underneath the text it needs to be blocked in everything you do on that side page. when the button is been released again, then the user can continue going through the site page.

I was thinking in a kind of a script in php, what is able to read the script below... and generates a popup

python script running on raspberry pi 3 running at start up

---------------------------------------------

import RPi.GPIO as GPIO
import time
import os

# Setup the Pin with Internal pullups enabled and PIN in reading mode.
GPIO.setmode(GPIO.BCM)
#GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(27, GPIO.IN, pull_up_down = GPIO.PUD_UP) # announcement switch
GPIO.setup(26, GPIO.OUT) # announcement led
GPIO.output(26, GPIO.HIGH) # setup led low

while True:
button = GPIO.input(27)
if button == False:
print("Button pressed")
GPIO.output(26, GPIO.LOW)
time.sleep(2)
GPIO.output(26, GPIO.HIGH)
# this is the script that will be called to block the website with a popup notification ??
# ?????


Any help would be appreciate

Samuel

ghp
Posts: 1418
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: button pressed > popup on webpage

Tue Mar 21, 2017 3:20 pm

Hello,
this is not a simple task.
The scenario is: a web page is displayed in a browser; the server is the pi. When button at pi is pressed, in the browser a popup should be displayed (without refreshing the page).
A simple setup could be:
- A web server which provides a webpage.
- the webpage has embedded javascript which in background calls a CGI-script on server.
- the cgi-script gets button state
- and based on this state the javascript displays popup in browser.

A more advanced system is:
-server side, a web framework, e.g. cherrypy which supports websockets
- websockets build the 'online' link with the browser
- a browser (client side)
The web framework provides a page with embedded javascript which opens the client side websocket connection, and displays popup as needed.
The web framework contains code which provides the button events into the websocket.
And you need a thread which records button presses and feeds these events to the web framework.

For the simple setup, you need:
* apache2, available on pi
* learn how to provide web pages
* how to embed javascript in web pages
* learn about javascript, and time based execution of javascript in browser.
* learn about html documents and how these are produced by javascript.
* set up CGI on apache2, and use python code to grab button state.
Many steps to master, but a lot of interesting technologies.
Regards,
Gerhard

sboerhoop
Posts: 3
Joined: Tue Mar 21, 2017 1:45 pm

Re: button pressed > popup on webpage

Mon Apr 10, 2017 8:26 pm

This is what i get so far: announcement button:
# !/bin/python
# Simple script for shutting down the raspberry Pi at the press of a button.

import RPi.GPIO as GPIO
import time
import os

# Setup the Pin with Internal pullups enabled and PIN in reading mode.
GPIO.setmode(GPIO.BCM)
#GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(27, GPIO.IN, pull_up_down = GPIO.PUD_UP) # announcement switch
GPIO.setup(26, GPIO.OUT) # announcement led
GPIO.output(26, GPIO.HIGH) # setup led low

while True:
button = GPIO.input(27)
if button == False:
print("Button pressed")
GPIO.output(26, GPIO.LOW)
time.sleep(2)
GPIO.output(26, GPIO.HIGH)

This is the button.php page
---------------------------------------------------------------
<!doctype html>

<html>

<head>

<title>Announcement button Status</title>
<meta http-equiv="refresh" content="5" >
</head>
<body>
<h2>Announcement button Status</h2>
<p>
<p style="font-family: calibri; font-size:14pt; font-style:italic">
<br><br>
<?php
// Set up valid status list
$state[1] = "<span style=\"color:green\">System is Running</span>";
$state[0] = "<span style=\"color:red\">Announcement made by Captian or Cabin Crew</span>";
?>
<?php $pinStatus = trim(shell_exec("gpio -g read 27")); // button input
//returns 0 = low; 1 = high
echo $state[$pinStatus];?>
<br><br>
</p>

</body>
</html>
---
on the button.php way, it change the text colour when the external button is pressed.
How can i get a popup message when i press the external button?
actually the page is doing now every 5 seconds a refresh. but the refresh only needs to happen
when the external button is been pressed. and the rest of the page doesn't need to be refreshed.

Who can help me?

maurice1
Posts: 37
Joined: Tue Mar 05, 2013 8:55 am
Location: Dublin

Re: button pressed > popup on webpage

Wed Apr 12, 2017 12:19 pm

Hi sboerhoop
I'm not quite sure what you require but maybe the following is a different way of thinking about your challenge.

Regarding your index.php and wanting a button to show to show the state of a switch perhaps using a iframe buttonstate.php embedded in index.php.
If buttonstate.php has <meta http-equiv="refresh" content="1" > then it will just refresh the button and not the whole webpage.

Regarding blocking the webpage if the button is pressed why not just make 2 copies of index.php in 2 separate folders and when the button is pressed copy the one you want displayed into var/www/html/ . When the button is released copy the other index.php instead

Alternatively I may have totally misunderstood what you were looking for.

ghp
Posts: 1418
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: button pressed > popup on webpage

Fri Apr 14, 2017 12:37 pm

Hello,
for 'scratchClient', I use an embedded python web app server to display configuration and real time state.
So far I use cherrypy + ws4py, but as cherrypy is somewhat complex and ws4py api was broken some time, I evaluated tornado with websockets.
The sample code provides a web application with websocket which displays state of a GPIO pin on localhost:8080
Hope this helps
Gerhard

Code: Select all

#!/usr/bin/python2
# -*- coding: utf-8 -*-

# sudo pip install tornado

import tornado.ioloop
import tornado.web
import tornado.websocket

import threading
import time
import Queue

# debug = True: set for a blink signal, no GPIO usage
# debug = False: set for GPIO usage

debug = False

if not debug:
    import RPi.GPIO as GPIO
    
# messages from Periphaeral Class to Websocket
sendQueue= Queue.Queue()

class PeripheralDebug:
    def __init__(self, sendQueue):
        self.sendQueue = sendQueue
        
    def start(self):
        self.runit = True
        blinkThread = threading.Thread(target=self.blink)
        blinkThread.start()
 
    def stop(self):
        self.runit = False
               
    def blink(self):
        cnt = 0
        while self.runit:
            self.sendQueue.put( { 'data': 'on', 'cnt' : cnt } )
            cnt += 1
            time.sleep(0.5)
            self.sendQueue.put( { 'data': 'off', 'cnt' : cnt } )
            cnt += 1
            time.sleep(0.5)

class PeripheralGPIO:
    def __init__(self, sendQueue):
        self.sendQueue = sendQueue
        
        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)
        
        self.channel = 4
        
        GPIO.setup(self.channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    def start(self):
        self.runit = True
        blinkThread = threading.Thread(target=self.run)
        blinkThread.start()

    def stop(self):
        self.runit = False
        
    def run(self):
        cnt = 0
        prev = None
        while self.runit:
            res =  GPIO.input(self.channel)
            if prev != res:
                if res:
                    self.sendQueue.put( { 'data': 'on', 'cnt' : cnt } )
                else:
                    self.sendQueue.put( { 'data': 'off', 'cnt' : cnt } )
                cnt += 1
                prev = res
            # for debouncing and limiting number of events per time
            time.sleep(0.01)
            

class PeripheralFactory:
    @staticmethod
    def getPeripheral(debug):
        if debug:
            return PeripheralDebug(sendQueue)
        else:
            return PeripheralGPIO(sendQueue)
                    
peripheral = PeripheralFactory.getPeripheral(debug)
peripheral.start()

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write( """<html>
    <head>
        <title>Websocket sample</title>
    </head>
    <body>
        Sample connection to a Raspberry Pi
        <hr/>
        <div>
           <div  style="position:relative; width:400px; height:80px;" >
               <div id="addr" style="width:400px; height:20px;">    addr    </div>
               <div id="status" style="width:400px; height:20px;">  status  </div>
               <div id="msg" style="width:400px; height:20px;">     message </div>
           </div>
        </div>

        <hr/>

        Connection Status
        <div id="connection" style="position:relative; width:200px; height:40px;background:lightgrey; font: 30px arial, sans-serif;" >
            connection
        </div>
        Message display
        <div id="feld" style="position:relative; width:200px; height:40px;background:lightgrey; font: 30px arial, sans-serif;" >
            message
        </div>
    
 
         <script type="text/javascript">
    "use strict";
   
    console.log("starting...");
    var addr = "ws://" + window.location.hostname + ":" + window.location.port + "/ws";
    console.log(addr);
    document.getElementById("addr").innerHTML = addr;
    var websocket = new WebSocket( addr );
   
    websocket.onmessage = function(e){
        var server_message = e.data;
        var obj = JSON.parse(server_message);
        
        document.getElementById("feld").innerHTML = obj.data;
        if ( obj.data == "on" )
        {
            document.getElementById("feld").style.background = 'yellow';
        } 
        else 
        {
            document.getElementById("feld").style.background = 'lightblue';
        }
        console.log(server_message);
        document.getElementById("msg").innerHTML = server_message;
    }
   
    websocket.onopen = function(){
       console.log('Connection open!');
       document.getElementById("connection").style.background = 'lightgreen';
       document.getElementById("status").innerHTML = 'connected !';
    }
   
    websocket.onclose = function(){
       console.log('Connection closed');
       document.getElementById("connection").style.background = 'red';
       document.getElementById("status").innerHTML = 'disconnected';
    }
    
    function onClick() {
              try {
                websocket.send( JSON.stringify( { click:1 } ) );
            }
            catch(err) {
                console.log( err.message );
            }
    }
      
    document.getElementById("feld").addEventListener("click", onClick);
  </script>
    </body>
</html>""" )
 
runMessageSend = True        
class ClientWebSocketHandler(tornado.websocket.WebSocketHandler):

    def __init__(self, args, kwargs):
        tornado.websocket.WebSocketHandler.__init__(self, args, kwargs)
        print("ClientWebSocketHandler.init")
        
        self.my_thread = threading.Thread(target = self.run)
        self.my_thread.start()
        
    def run(self):
        while runMessageSend:
            try:
                s = sendQueue.get(block=True, timeout=0.1)
            except Exception:
                continue  
            if self.ws_connection is None:
                print("discard ", s)  
            else:
                print("send ", s)  
                try:
                    self.write_message(s )
                except Exception:
                    pass
            
    def open(self, *args, **kwargs):
        print("open", args, kwargs)

    def on_close(self, *args, **kwargs):
        print ("on_close", args, kwargs)

    def on_message(self, m):
        print ( "received", m )
        
def make_app():
    return tornado.web.Application(
                 [ 
                     (r"/"  , MainHandler), 
                     (r"/ws", ClientWebSocketHandler), 
                 ]
                )

if __name__ == "__main__":
    print("start")
    app = make_app()
    app.listen(8080)
    try:
        tornado.ioloop.IOLoop.current().start()
    except KeyboardInterrupt:
        peripheral.stop()
        runMessageSend = False
        tornado.ioloop.IOLoop.current().stop()
    print("stopped")

JonathanOnwave
Posts: 2
Joined: Mon Oct 08, 2018 7:43 am

Re: button pressed > popup on webpage

Tue Jan 08, 2019 11:56 am

@Gerhard - thanks so much for sharing this - I learned A LOT from studying your code.
Then I found your excellent web page explaining it which I'm sharing a link to here for others who find this page by searching: http://heppg.de/ikg/wordpress/?p=971

Great work, thanks again!

Return to “Python”