Getting Data from script.py to index.html examples *Re-Post"

3,324 views
Skip to first unread message

Toshi Bass

unread,
Feb 19, 2015, 7:38:30 AM2/19/15
to web...@googlegroups.com
In the light of some observations I have re-posted this topic with some optimized code that should offer more stability and hopefully be easier to understand.

There has been a lot of questions recently regarding using macros to get info from script.py into index.html, and it is clear a lot of people are struggle with this, therefore I have produced the following method to try to ease this process.

I will attach Index.html files as they do not need any properties changing when there copied into a directory, however for Noobs the python script should be copied and pasted from this post into the existing script.py

With this method you can add up to 10 Data Variables or String Variables (i0 to i9) and they will be "returned" (in a json string named lista) to the index.html file each time the info is requested,
You do not need to use all 10 Variables and if you want more its a simple case to add more like  i11,i12.................. 

Basic getData script 

#!/usr/bin/python
# Toshi Bass
# Python 3.2 Raspbian (Wheezy) V7

# Imports
import webiopi
import json
import sys
import time
import datetime
import os
import subprocess

sys.path.append("/home/pi/webiopi/htdocss") # Revise to your path

# Enable debug output
webiopi.setDebug()
from webiopi.utils.logger import info

# Retrieve GPIO lib
GPIO = webiopi.GPIO

##################################################################
# Import Connected Devices (Only devices supported by webiopi)
##################################################################



##################################################################
# Called by WebIOPi at script loading
##################################################################

LED1 = 25

def setup():
    webiopi.debug("Script with macros - Setup")
    # Setup GPIOs

    GPIO.setFunction(LED1, GPIO.OUT)

##################################################################
# Setup Vars
##################################################################

i0,i1,i2,i3,i4,i5,i6,i7,i8,i9 = 0,0,0,0,0,0,0,0,0,0

##################################################################
# Define Functions
##################################################################


    
##################################################################
# Looped by WebIOPi
##################################################################

def loop():
    # Toggle LED each 5 seconds
    value = not GPIO.digitalRead(LED1)
    GPIO.digitalWrite(LED1, value)
    print()
    print("_____ watch dog _____",int(value))
    print()

    webiopi.sleep(5)        

##################################################################
# Called by WebIOPi at server shutdown
##################################################################

def destroy():
    webiopi.debug("Script with macros - Destroy")
    # Reset GPIO functions

    GPIO.setFunction(LED1, GPIO.IN)

##################################################################
# Macros
##################################################################

@webiopi.macro
def getData():
    global i0,i1,i2,i3,i4,i5,i6,i7,i8,i9

    i0=4567
    i1=12345


    i9=("Toshi")
    
    lista = i0,i1,i2,i3,i4,i5,i6,i7,i8,i9
    print("lista",lista)
    return json.dumps (lista)

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

if you finish you project and want to tidy up the code you can delete all instances of iX that are not used, for instance if you only use i0 and i1 you can delete all instances of ,i2,i3,i4,i5,i6,i7,i8,i9
 
You can also delete the unused lines in the html file for example if your not using i9 the you delete  myDiv9.innerHTML = i[9] and the display line - <tr><td><div id="myDiv9"></div></td></tr>

Remember this rule, if you create a Div like myDiv9.innerHTML = i[9] then you need to display that Div in the <body> or the code will fail, so if you delete <tr><td><div id="myDiv9"></div></td></tr> in the <body> then you must also delete the line myDiv9.innerHTML = i[9]


Next is to add some sensor data

Toshi
index.html

Toshi Bass

unread,
Feb 19, 2015, 7:42:31 AM2/19/15
to web...@googlegroups.com
In the light of some observations I have re-posted this topic with some optimized code that should offer more stability and hopefully be easier to understand.

OK you got the previous Basic getData script and Index working now to add some sensor data, I am using two DS18B20 sensors that I have configured in the webiopi config file but the code is in the script to use the alternative method of importing the sensors.

To return other type of sensor data its a simple case to import the device, and in def GET_DATA(): give the data a i number for example if you have a MCP3008 ADC connected and set up as adc0 in the config file 

Just add adc0 =  = webiopi.deviceInstance("adc0")  after the line  Temp1 = webiopi.deviceInstance("Temp1")

and in def GET_DATA(): add a line like  i8 = adc0.analogRead(0)  see https://code.google.com/p/webiopi/wiki/ANALOG#Methods_list for list of adc functions

Similarly if you wanted to send the value of say GPIO23 you would just add a line in GET_DATA(): like i7 = GPIO.digitalRead(23)

I have included in GET_DATA(): a few examples. 

Basic getData script with sensors

#!/usr/bin/python
# Toshi Bass
# Python 3.2 Raspbian (Wheezy) V7

# Imports
import webiopi
import json
import sys
import time
import datetime
import os
import subprocess

sys.path.append("/home/pi/webiopi/htdocss") # Revise to your path

# Enable debug output
webiopi.setDebug()
from webiopi.utils.logger import info

# Retrieve GPIO lib
GPIO = webiopi.GPIO

##################################################################
# Import Connected Devices (Only devices supported by webiopi)
##################################################################
# There are two ways to import connected Devices into Python 
# 1st way is by entering details in the config file [DEVICE] section 
# there are examples of the syntax in : /etc/webiopi/config 
# Using 1st way allows you to check that the device is functioning
# in the Devices-Monitor.


from webiopi import deviceInstance

#DS18B20 Temperature sensor
Temp0 = webiopi.deviceInstance("Temp0")
Temp1 = webiopi.deviceInstance("Temp1")

#--------------------------------------------------------------------

# 2nd way is to import the device directly into Python via the
# webiopi driver (important for each specific device instance
# use only the 1st or 2nd way not both)


#from webiopi.devices.sensor import DS18B20

#DS18B20 Temperature sensor
#Temp0 = DS18B20(slave="28-00000XXXXXXXX") < your device serial number
#Temp1 = DS18B20(slave="28-00000XXXXXXXX") < your device serial number


##################################################################
# Called by WebIOPi at script loading
##################################################################

LED1 = 25

def setup():
    webiopi.debug("Script with macros - Setup")
    # Setup GPIOs
    GPIO.setFunction(4, GPIO.OUT)
    GPIO.setFunction(LED1, GPIO.OUT)

##################################################################
# Setup Vars
##################################################################

i0,i1,i2,i3,i4,i5,i6,i7,i8,i9 = 0,0,0,0,0,0,0,0,0,0

##################################################################
# Define Functions
##################################################################



    
##################################################################
# Looped by WebIOPi
##################################################################

def loop():
    # Toggle LED each 5 seconds
    value = not GPIO.digitalRead(LED1)
    GPIO.digitalWrite(LED1, value)
    print()
    print("_____ watch dog _____",int(value))


    webiopi.sleep(5)        

##################################################################
# Called by WebIOPi at server shutdown
##################################################################

def destroy():
    webiopi.debug("Script with macros - Destroy")
    # Reset GPIO functions

    GPIO.setFunction(LED1, GPIO.IN)

##################################################################
# Macros
##################################################################

@webiopi.macro
def getData():
    global i0,i1,i2,i3,i4,i5,i6,i7,i8,i9

    i0=4567

    #Time
    now = datetime.datetime.now()
    i1 = (now.hour,now.minute,now.second)

    #cpu temp
    res = os.popen('vcgencmd measure_temp').readline()
    i2 =(res.replace("temp=","").replace("'C\n",""))

    #cpu load
    idle = subprocess.check_output(["vmstat | awk '{print $15}'"], shell=True)  
    i3 = 100 - (int(idle.split()[1])) 

    #DS18B20 Temperatures
    i4= "%.2f" % (Temp0.getCelsius())
    i5= "%.2f" % (Temp1.getCelsius())


    i9=("Toshi")
    
    lista = i0,i1,i2,i3,i4,i5,i6,i7,i8,i9
    #Return the result from GET_DATA to index.html
    print("lista",lista)
    return json.dumps (lista)

##################################################################

Next is to add gauges

Toshi
index.html

Toshi Bass

unread,
Feb 19, 2015, 7:45:49 AM2/19/15
to web...@googlegroups.com
In the light of some observations I have re-posted this topic with some optimized code that should offer more stability and hopefully be easier to understand.

OK you got the previous Basic getData script and Index with sensors working now you want gauges to show your values.

There's is a previous example how to do this here   https://groups.google.com/d/msg/webiopi/tm5b-67IwfQ/BjtEN_ymtA4   but I will include the instructions here again :

Head over to http://justgage.com/ and click on download, unzip the file and copy the directory named resources into your path were your script and index files are so for example if your script.py and index.html files are in /home/pi/webiopi/examples/scripts/macros so the directory tree will look like this /home/pi/webiopi/examples/scripts/macros/resources/js 
its important to get this correct or the gauges wont work.


The alternative is to modify the following two lines that point to the path in the new index.html attached, but I find that much harder to do.

<script src="resources/js/raphael.2.1.0.min.js"></script>
<script src="resources/js/justgage.1.0.1.min.js"></script>

The same script.py is used its just the attached index.html file that changes.


Next is to add labels to buttons


Toshi

index.html

Toshi Bass

unread,
Feb 19, 2015, 7:56:47 AM2/19/15
to web...@googlegroups.com
In the light of some observations I have re-posted this topic with some optimized code that should offer more stability and hopefully be easier to understand.

OK you got the previous Basic getData script and Index with sensors and gauges this addition adds 2 label buttons for GPIO23 and 24

The operation to get the current state of the GPIO's could be done in getData() however considering the delay involved with getting the temperatures etc you will notice I added a dedicated macro  getGPIO(): to optimize the speed.

Obviously the index.html file also has the associated dedicated macro. 

# webiopi driver (important for each spacific device instance
# use only the 1st or 2nd way not both)


#from webiopi.devices.sensor import DS18B20

#DS18B20 Temperature sensor
#Temp0 = DS18B20(slave="28-00000XXXXXXXX") < your device serial number
#Temp1 = DS18B20(slave="28-00000XXXXXXXX") < your device serial number


##################################################################
# Called by WebIOPi at script loading
##################################################################
switch1 = 23
switch2 = 24
LED1 = 25

def setup():
    webiopi.debug("Script with macros - Setup")
    # Setup GPIOs
    GPIO.setFunction(switch1, GPIO.OUT)
    GPIO.setFunction(switch2, GPIO.OUT)
    GPIO.setFunction(LED1, GPIO.OUT)

##################################################################
# Setup Vars
##################################################################

i0,i1,i2,i3,i4,i5,i6,i7,i8,i9 = 0,0,0,0,0,0,0,0,0,0

##################################################################
# Define Functions
##################################################################


    
##################################################################
# Looped by WebIOPi
##################################################################

def loop():
    # Toggle LED each 5 seconds
    value = not GPIO.digitalRead(LED1)
    GPIO.digitalWrite(LED1, value)
    print()
    print("_____ watch dog _____",int(value))
    print()

    webiopi.sleep(5)        

##################################################################
# Called by WebIOPi at server shutdown
##################################################################

def destroy():
    webiopi.debug("Script with macros - Destroy")
    # Reset GPIO functions
    GPIO.setFunction(switch1, GPIO.IN)
    GPIO.setFunction(switch2, GPIO.IN)
    GPIO.setFunction(LED1, GPIO.IN)

##################################################################
# Macros
##################################################################

@webiopi.macro
def getData():
    global i0,i1,i2,i3,i4,i5,i6,i7,i8,i9

    i0=4567

    #Time
    now = datetime.datetime.now()
    i1 = (now.hour,now.minute,now.second)

    #cpu temp
    res = os.popen('vcgencmd measure_temp').readline()
    i2 =(res.replace("temp=","").replace("'C\n",""))

    #cpu load
    idle = subprocess.check_output(["vmstat | awk '{print $15}'"], shell=True)  
    i3 = 100 - (int(idle.split()[1])) 

    #DS18B20 Temperatures
    i4= "%.2f" % (Temp0.getCelsius())
    i5= "%.2f" % (Temp1.getCelsius())

    i9=("Toshi")
    
    lista = i0,i1,i2,i3,i4,i5,i6,i7,i8,i9
    print("lista",lista)
    return json.dumps (lista)

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

@webiopi.macro
def getGPIO():

    sw1 = int(GPIO.digitalRead(switch1))
    sw2 = int(GPIO.digitalRead(switch2))

    listsw = sw1,sw2
    print("listsw",listsw)
    return json.dumps (listsw)

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

Toshi
index.html

Toshi Bass

unread,
Feb 19, 2015, 8:01:44 AM2/19/15
to web...@googlegroups.com
In the light of some observations I have re-posted this topic with some optimized code that should offer more stability and hopefully be easier to understand.

OK you got the previous Basic getData script and Index with sensors and gauges and 2 labeled GPIO buttons working, however the function webiopi().toggleValue(x) only works for the standard GPIO therefore I have changed the code from GPIO buttons to Digital Expander buttons.

The example uses a 8 channel onewire DS2408 however the same code will work for the MCP family of digital expanders (well the first 8 channels) just change all instances of IOC1 to MCP0 or whatever you call your MCPXXXXX

Its relatively easy to add more buttons if you so desire or delete some buttons and associated code if you want say only 2 or 3 buttons) 

For the piface see the bottom of the post.

# DS18B20 Temperature sensor
Temp0 = webiopi.deviceInstance("Temp0")
Temp1 = webiopi.deviceInstance("Temp1")


#MCP 23017
#mcp0 = webiopi.deviceInstance("mcp0")

#PiFaceDigital
#pfd = webiopi.deviceInstance("pfd")


#DS2408
IOC1 = webiopi.deviceInstance("IOC1")


#--------------------------------------------------------------------

# 2nd way is to import the device directly into Python via the
# webiopi driver (important for each spacific device instance
# use only the 1st or 2nd way not both)

#from webiopi.devices.sensor import DS18B20

#DS18B20 Temperature sensor
#Temp0 = DS18B20(slave="28-00000XXXXXXXX") < your device serial number
#Temp1 = DS18B20(slave="28-00000XXXXXXXX") < your device serial number

#from webiopi.devices.digital.mcp23XXX import MCP23017

#mcp0 = MCP23017(slave=0x20)


##################################################################
# Called by WebIOPi at script loading
##################################################################

LED1 = 25

Switch0 = 0
Switch1 = 1
Switch2 = 2
Switch3 = 3
Switch4 = 4
Switch5 = 5
Switch6 = 6
Switch7 = 7

def setup():
    webiopi.debug("Script with macros - Setup")
    # Setup GPIOs
    GPIO.setFunction(LED1, GPIO.OUT)

# Setup function for IOC1 (DS2408)
    for x in range(0, 8):
        IOC1.setFunction(x,GPIO.OUT)

# Setup state for IOC1 (DS2408)
    for x in range(0, 8):
        IOC1.digitalWrite(x,GPIO.LOW)

##################################################################
# Setup Vars
##################################################################

i0,i1,i2,i3,i4,i5,i6,i7,i8,i9 = 0,0,0,0,0,0,0,0,0,0

p0,p1,p2,p3,p4,p5,p6,p7 = 0,0,0,0,0,0,0,0

##################################################################
# Define Functions
##################################################################




##################################################################
# Looped by WebIOPi
##################################################################

def loop():
    # Toggle LED each 5 seconds
    value = not GPIO.digitalRead(LED1)
    GPIO.digitalWrite(LED1, value)
    print()
    print("_____ watch dog _____",int(value))
    print()


    webiopi.sleep(5)        

##################################################################
# Called by WebIOPi at server shutdown
##################################################################

def destroy():
    webiopi.debug("Script with macros - Destroy")
    # Reset GPIO functions

    GPIO.setFunction(LED1, GPIO.IN)

    for x in range(0, 8):
        IOC1.setFunction(x,GPIO.IN)
# Use the pin (number) sent from index.html and toggle state of that pin on IOC1 (0 to 1 or 1 to 0)
@webiopi.macro
def setPIO(number):
    value = not IOC1.digitalRead(int(number))
    IOC1.digitalWrite(int(number),value)  
    print (number,(int(value)))

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

#Return the current state (0 or 1) of the first 8 pins of IOC1
@webiopi.macro
def getPIO():
    global p0,p1,p2,p3,p4,p5,p6,p7

    p0= int(IOC1.digitalRead(Switch0))
    p1= int(IOC1.digitalRead(Switch1))
    p2= int(IOC1.digitalRead(Switch2))
    p3= int(IOC1.digitalRead(Switch3))
    p4= int(IOC1.digitalRead(Switch4))
    p5= int(IOC1.digitalRead(Switch5))
    p6= int(IOC1.digitalRead(Switch6))
    p7= int(IOC1.digitalRead(Switch7))

    listb = p0,p1,p2,p3,p4,p5,p6,p7
    print("listb",listb)
    return json.dumps (listb)

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

For piface as the output are fixed you need to delete the following in def setup() and again in def destroy():-

# Setup function for IOC1 (DS2408)
    for x in range(0, 8):
        IOC1.setFunction(x,GPIO.OUT)

In def setPIO(number): you will need to modify in red  

# Use the pin (number) sent from index.html and toggle state of that pin on IOC1 (0 to 1 or 1 to 0)
@webiopi.macro
def setPIO(number):
    value = not IOC1.digitalRead(int(number))
    IOC1.digitalWrite(int(number),value)  
    print (number,(int(value)))

to:

# Use the pin (number) sent from index.html and toggle state of that pin on pfd (0 to 1 or 1 to 0)
@webiopi.macro
def setPIO(number):
    value = not pfd.digitalRead(int(number))
    pfd.digitalWrite(Output(number),value)  # I think that would work !
    print (number,(int(value)))

Then change all instance of IOC1 for pfd in the script as well as index.html and it should work fine.

Toshi

index.html

Toshi Bass

unread,
Feb 19, 2015, 8:06:08 AM2/19/15
to web...@googlegroups.com
In the light of some observations I have re-posted this topic with some optimized code that should offer more stability and hopefully be easier to understand.

Buttons do not need to just switch GPIO or Expander pins like MCP23017 or Piface they can simply toggle the value of a variable in your script or indeed set whatever value you want to a variable the way to do this is identical to toggling a output pin but you toggle to variable instead then send its new value back to index.html this simple example shows this working:


#!/usr/bin/python
# Toshi Bass
# Python 3.2 Raspbian (Wheezy) V7

# Imports
import webiopi
import json
import sys
import time
import datetime
import os

sys.path.append("/home/pi/webiopi/htdocss") # Revise to your path

# Enable debug output
webiopi.setDebug()
from webiopi.utils.logger import info

# Retrieve GPIO lib
GPIO = webiopi.GPIO

##################################################################
# Import Connected Devices (Only devices supported by webiopi)
##################################################################



##################################################################
# Called by WebIOPi at script loading
##################################################################



##################################################################
# Setup Vars
##################################################################

V0,V1,V2,V3=0,0,0,0

##################################################################
# Define Functions
##################################################################




##################################################################
# Looped by WebIOPi
##################################################################

def loop():
    global V0

    # Toggle V0 each 5 seconds
    value = not V0
    V0 = int(value)

    print()
    print("_____ watch dog _____V =",int(value))
    print()



    webiopi.sleep(5)

##################################################################
# Called by WebIOPi at server shutdown
##################################################################

#def destroy():



##################################################################
# Macros
##################################################################

@webiopi.macro
def getData():
    global V0,V1,V2,V3
    listV = V0,V1,V2,V3

    print("listV",listV)
    return json.dumps (listV)

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

@webiopi.macro
def set_V(number):
    global V0,V1,V2,V3

    if int(number) == 0:
        if V0 == 0:
            V0 = 1
        else:
            V0 = 0 

    if int(number) == 1:
        if V1 == 0:
            V1 = 1
        else:
            V1 = 0 

    if int(number) == 2:
        if V2 == 0:
            V2 = 1
        else:
            V2 = 0 

    if int(number) == 3: 
        if V3 == 0:
            V3 = 1
        else:
            V3 = 0 

    getData()

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

Toshi
index.html

Toshi Bass

unread,
Feb 19, 2015, 8:14:31 AM2/19/15
to web...@googlegroups.com
In the light of some observations I have re-posted this topic with some optimized code that should offer more stability and hopefully be easier to understand.

In this example instead of having a webpage displaying a centered vertical line of buttons and gauges, we see 1 way  of positioning the elements, by using a table, the script.py from the following post is used but I will modify the index.html file for this example: 


I say 1 way because I know there are several ways to position stuff on a web page and I am not saying this is the best way or a good way or even if its a crap way, but it is how I tend to do it only because its the easy way I found for me to get a symmetrical result.

The first thing to understand is how the example above displays the element in a vertical line:

<body>
<div id="content" align="center"></div>                       // this positions all the elements with an  id of  "content"  centrally on the web page
  <table align="center" border="1" width="160px"></tr>   // this adds a table element of the same size as the buttons in   id="content"
<tr><td><div id="myDiv0"></div></td></tr>        // each of these lines adds another row in table with a cell element like id="myDiv0"
<tr><td><div id="myDiv1"></div></td></tr>
<tr><td><div id="myDiv2"></div></td></tr>
<tr><td><div id="myDiv3"></div></td></tr>
<tr><td><div id="myDiv4"></div></td></tr>
<tr><td><div id="myDiv5"></div></td></tr>
<tr><td><div id="myDiv8"></div></td></tr>
<tr><td><div id="myDiv9"></div></td></tr>
<tr><td><div id="g1"></div></td></tr>              // each of these lines adds another row in table with a gauge like id="g1"
<tr><td><div id="g2"></div></td></tr>
<tr><td><div id="g3"></div></td></tr>
<tr><td><div id="g4"></div></td></tr>
  </table>
</body>

Its clear that if we want to be able to control the positions of the buttons then we need to give each button a separate "id" instead of the current multiple elementid="content"

So the first modification to the example to give each button it own "id" is to remove   content.append(button);   and instead have     $("#cell_Switch1").append(button); etc :

//create a button which call GETPIO function - for GPIO 23  
                button = webiopi().createButton("macro0", "Switch 1", callMacro_SETPIO23);
$("#cell_Switch1").append(button); // append button to content div
webiopi().setClass("macro0", "OFF"); //set color state

// create a button which call GETPIO function - for GPIO 24  
                button = webiopi().createButton("macro1", "Switch 2", callMacro_SETPIO24);
$("#cell_Switch2").append(button); // append button to content div
webiopi().setClass("macro1", "OFF"); //set color state

// create a "LED" labeled button for GPIO 25
button = webiopi().createGPIOButton(25, "LED1");
$("#cell_Switch3").append(button); // append button to content div

Now we have separate Id's for the buttons we cant recreate in one table like this:

<body>
  <table align="center" border="1" ></tr>

<tr><td><div id="cell_Switch1"></div></td></tr>
<tr><td><div id="cell_Switch2"></div></td></tr>
<tr><td><div id="cell_Switch3"></div></td></tr>

<tr><td><div id="myDiv0"></div></td></tr>
<tr><td><div id="myDiv1"></div></td></tr>
<tr><td><div id="myDiv2"></div></td></tr>
<tr><td><div id="myDiv3"></div></td></tr>
<tr><td><div id="myDiv4"></div></td></tr>
<tr><td><div id="myDiv5"></div></td></tr>
<tr><td><div id="myDiv8"></div></td></tr>
<tr><td><div id="myDiv9"></div></td></tr>
<tr><td align="center"><div id="g1"></div></td></tr>
<tr><td align="center"><div id="g2"></div></td></tr>
<tr><td align="center"><div id="g3"></div></td></tr>
<tr><td align="center"><div id="g4"></div></td></tr>
  </table>
</body>

Now we have each element in its own table cell we can design a new table .  

<tr> designates a table row. Each <tr...> element contains one or more <td ...> or <th ...> elements. so to produce a table which is 3 rows:

         <table align="center" border="1">
<tr><td>A</td></tr>
<tr><td>B</td></tr>
<tr><td>C</td></tr>
  </table>

To add 5 columns in each row:

          <table align="center" border="1">
<tr><td>A</td> <td>A</td> <td>A</td> <td>A</td> <td>A</td></tr>
<tr><td>B</td> <td>B</td> <td>B</td> <td>B</td> <td>B</td></tr>
<tr><td>C</td> <td>C</td> <td>C</td> <td>C</td> <td>C</td></tr>
  </table>

At this point its advisable to split up each table row <tr> and write it like this so its easier to read:

          <table align="center" border="1">
<tr>
                       <td>A</td>  
                       <td>A</td> 
                       <td>A</td> 
                       <td>A</td> 
                       <td>A</td> 
                </tr>

<tr>
                       <td>B</td>  
                       <td>B</td> 
                       <td>B</td> 
                       <td>B</td> 
                       <td>B</td> 
                </tr>

<tr>
                       <td>C</td>  
                       <td>C</td> 
                       <td>C</td>
                       <td>C</td> 
                       <td>C</td>
                </tr>
  </table>

Then replace the A B C's  with the cell id's (just remember one thing - If you make a $("#cell_.......").append(button); or a myDiv....innerHTML = something or a var g1 = new JustGage(...... etc etc then you have to display them somewere or the code will fail.)

  <table align="center" border="8">
<tr align="center">
<td><div id="myDiv0"></div></td> 
<td><div id="myDiv1"></div></td> 
<td><div id="myDiv2"></div></td> 
<td><div id="g1"></div></td> 
<td><div id="g2"></div></td>
</tr>

<tr align="center">
<td><div id="myDiv3"></div></td> 
<td><div id="myDiv4"></div></td> 
<td><div id="myDiv5"></div></td> 
<td><div id="g3"></div></td> 
<td><div id="g4"></div></td>
</tr>

<tr align="center">
<td><div id="cell_Switch1"></div></td> 
<td><div id="cell_Switch2"></div></td> 
<td><div id="cell_Switch3"></div></td> 
<td><div id="myDiv8"></div></td> 
<td><div id="myDiv9"></div></td>
</tr>
  </table> 

Your now in the wonderfully frustrating world of css and <tables> you can do anything with tables but for me there was a lot of trial and error, best is to decide what you want the table to look like and google html <table> bla bla bla to find out how to do stuff like rowspan, colspan, color, font etc etc etc .


Toshi
index.html
CP.JPG

Toshi Bass

unread,
Feb 20, 2015, 12:06:13 PM2/20/15
to web...@googlegroups.com
This example shows how to make a time switch that will switch a GPIO & Button On and Off at certain times, in its self quite simple, but I tried my best to complicate it by making the time for On and Off select-able from the web page, I also replace the time display which is currently generated in python into a javaScript date and time function.

#!/usr/bin/python
# Toshi Bass
# Python 3.2 Raspbian (Wheezy) V7

# Imports
import webiopi
import json
import sys
import time
import datetime
import os
import subprocess

sys.path.append("/home/pi/webiopi/htdocss") # Revise to your path

# Enable debug output
webiopi.setDebug()
from webiopi.utils.logger import info

# Retrieve GPIO lib
GPIO = webiopi.GPIO

##################################################################
# Import Connected Devices (Only devices supported by webiopi)
##################################################################
# There are two ways to import connected Devices into Python 
# 1st way is by entering details in the config file [DEVICE] section 
# there are examples of the syntax in : /etc/webiopi/config 
# Using 1st way allows you to check that the device is functioning
# in the Devices-Monitor.


from webiopi import deviceInstance

#DS18B20 Temperature sensor
Temp0 = webiopi.deviceInstance("Temp0")
Temp1 = webiopi.deviceInstance("Temp1")

#--------------------------------------------------------------------

# 2nd way is to import the device directly into Python via the
# webiopi driver (important for each spacific device instance
# use only the 1st or 2nd way not both)


#from webiopi.devices.sensor import DS18B20

#DS18B20 Temperature sensor
#Temp0 = DS18B20(slave="28-00000XXXXXXXX") < your device serial number
#Temp1 = DS18B20(slave="28-00000XXXXXXXX") < your device serial number


##################################################################
# Called by WebIOPi at script loading
##################################################################
switch1 = 23
switch2 = 24
LED1 = 25
Timed_switch = 27

def setup():
    webiopi.debug("Script with macros - Setup")
    # Setup GPIOs
    GPIO.setFunction(switch1, GPIO.OUT)
    GPIO.setFunction(switch2, GPIO.OUT)
    GPIO.setFunction(LED1, GPIO.OUT)
    GPIO.setFunction(Timed_switch, GPIO.OUT)

##################################################################
# Setup Vars
##################################################################

i0,i1,i2,i3,i4,i5,i6,i7,i8,i9 = 0,0,0,0,0,0,0,0,0,0


# Set initial Time Clock Vars
 
hour_off   = 23 # Turn Timed_switch Off
minute_off = 00

hour_on    = 16 # Turn Timed_switch On
minute_on  = 30

##################################################################
# Define Functions
##################################################################


    
##################################################################
# Looped by WebIOPi
##################################################################

def loop():
    global hour_off, minute_off, hour_on, minute_on

    # Toggle LED each 5 seconds
    value = not GPIO.digitalRead(LED1)
    GPIO.digitalWrite(LED1, value)
    print()
    print("_____ watch dog _____",int(value))
    print()

    # retrieve current datetime
    now = datetime.datetime.now()

    # Turn Timed_switch On
    if ((now.hour == hour_on) and (now.minute == minute_on)):
        if GPIO.digitalRead(Timed_switch)==0:
            GPIO.digitalWrite(Timed_switch, 1) 

    # Turn Timed_switch Off
    if ((now.hour == hour_off) and (now.minute == minute_off)):
        if GPIO.digitalRead(Timed_switch)==1:
            GPIO.digitalWrite(Timed_switch, 0)

    print(hour_off, minute_off, hour_on, minute_on)

    webiopi.sleep(5)        

##################################################################
# Called by WebIOPi at server shutdown
##################################################################

def destroy():
    webiopi.debug("Script with macros - Destroy")
    # Reset GPIO functions
    GPIO.setFunction(switch1, GPIO.IN)
    GPIO.setFunction(switch2, GPIO.IN)
    GPIO.setFunction(LED1, GPIO.IN)
    GPIO.setFunction(Timed_switch, GPIO.IN)

##################################################################
# Macros
##################################################################

@webiopi.macro
def getData():
    global i0,i1,i2,i3,i4,i5,i6,i7,i8,i9

    i0=4567

    #Time - not used in index.html now.
    now = datetime.datetime.now()
    i1 = (now.hour,now.minute,now.second)

    #cpu temp
    res = os.popen('vcgencmd measure_temp').readline()
    i2 =(res.replace("temp=","").replace("'C\n",""))

    #cpu load
    idle = subprocess.check_output(["vmstat | awk '{print $15}'"], shell=True)  
    i3 = 100 - (int(idle.split()[1])) 

    #DS18B20 Temperatures
    i4= "%.2f" % (Temp0.getCelsius())
    i5= "%.2f" % (Temp1.getCelsius())

    i9=("Toshi")
    
    lista = i0,i1,i2,i3,i4,i5,i6,i7,i8,i9
    print("lista",lista)
    return json.dumps (lista)

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

@webiopi.macro
def getGPIO():

    sw1 = int(GPIO.digitalRead(switch1))
    sw2 = int(GPIO.digitalRead(switch2))
    sw3 = int(GPIO.digitalRead(Timed_switch))
    listsw = sw1,sw2,sw3
    print("listsw",listsw)
    return json.dumps (listsw)

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

# Macro to set the Time_Clock Times
@webiopi.macro
def set_Time_Clock(h_on,m_on,h_off,m_off):
    global hour_on,minute_on,hour_off,minute_off
    hour_on = int(h_on)
    minute_on = int(m_on)
    hour_off = int(h_off)
    minute_off = int(m_off)
    print (hour_on,minute_on,hour_off,minute_off)
    print()

# Macro to get the Time_Clock Times
@webiopi.macro
def get_Time_Clock_Time():
    global hour_on,minute_on,hour_off,minute_off
    print ("----GET CURRENT TIMES----",hour_on,minute_on,hour_off,minute_off)
    print()
    return json.dumps ([hour_on,minute_on,hour_off,minute_off])

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

It should be noted that new times set from the index file will not be retained if the python code is stopped, when script.py is restarted the times will revert back to the setup times detailed in the # Setup Vars section. 

Also the timer will only switch GPIO27 when the next set time is reached so if the set time for On is say 15.00 and Off at 18.00 and you start the script.py running at 17.00 the the next activation time will be Off at 18.00 and if the GPIO is already Off then you will see nothing happen until 15.00 the following day when GPIO27 will switch On, however you can manually press the "Timed Switch" button on the web page to toggle GPIO27 and the timer will switch GPIO27 when the next Off / On time comes around.   

I hope that's understandable if not just experiment with it to see how it works,

Toshi
index.html
TI.JPG

Toshi Bass

unread,
Feb 24, 2015, 7:04:37 AM2/24/15
to web...@googlegroups.com
So the limitation of the previous script was that if you shutdown the python script the new times set from the index file were not be retained, this example adds that facility, it uses python pickle to save a small txt file when the script is shutdown and retrieves it again when the script restarts, there may well be other ways of doing this but its how I do it and it works great.

There are no changes to the index.html file.


#!/usr/bin/python
# Toshi Bass
# Python 3.2 Raspbian (Wheezy) V7

# Imports
import webiopi
import json
import sys
import time
import datetime
import os
import subprocess
import pickle
##################################################################
# Retrieve saved Vars
##################################################################

global hour_off, minute_off, hour_on, minute_on
try:
    inFile = open('/home/pi/webiopi/myproject/saveVars.txt', 'rb') # substitute myproject for your working directory
    newList = pickle.load(inFile)
    inFile.close()
    hour_off, minute_off, hour_on, minute_on = newList
    print()
    print("Retreve SaveVars ",newList)
    print()
except Exception as e:
    print (e)
    print("Unable to access saveVars file")

    print("Loading initial Time Clock Vars instead")
    pass
    hour_off   = 23 # Turn Timed_switch Off
    minute_off = 00
    hour_on    = 16 # Turn Timed_switch On
    minute_on  = 30
    print("Time Clock Vars = ",hour_off, minute_off, hour_on, minute_on)

##################################################################
# Define Functions
##################################################################


    
##################################################################
# Looped by WebIOPi
##################################################################

def loop():
    global hour_off, minute_off, hour_on, minute_on

    # Toggle LED each 5 seconds
    value = not GPIO.digitalRead(LED1)
    GPIO.digitalWrite(LED1, value)
    print()
    print("_____ watch dog _____",int(value))
    print()

    # retrieve current datetime
    now = datetime.datetime.now()

    # Turn Timed_switch On
    if ((now.hour == hour_on) and (now.minute == minute_on)):
        if GPIO.digitalRead(Timed_switch)==0:
            GPIO.digitalWrite(Timed_switch, 1) 

    # Turn Timed_switch Off
    if ((now.hour == hour_off) and (now.minute == minute_off)):
        if GPIO.digitalRead(Timed_switch)==1:
            GPIO.digitalWrite(Timed_switch, 0)

    #print(hour_off, minute_off, hour_on, minute_on)

    webiopi.sleep(5)        

##################################################################
# Called by WebIOPi at server shutdown
##################################################################

def destroy():
    webiopi.debug("Script with macros - Destroy")

    # SaveVars
    global hour_off, minute_off, hour_on, minute_on
    useList = [hour_off, minute_off, hour_on, minute_on]
    print()
    print("SaveVars ",useList)
    print()
    outFile = open('/home/pi/webiopi/myproject/saveVars.txt', 'wb') # substitute myproject for your working directory
    pickle.dump(useList, outFile)
    outFile.close()

    # Reset GPIO functions
    GPIO.setFunction(switch1, GPIO.IN)
    GPIO.setFunction(switch2, GPIO.IN)
    GPIO.setFunction(LED1, GPIO.IN)
    GPIO.setFunction(Timed_switch, GPIO.IN)

##################################################################
# Macros
##################################################################

@webiopi.macro
def getData():
    global i0,i1,i2,i3,i4,i5,i6,i7,i8,i9

    i0=4567

    #Time
# Macro to set Time_Clock Times
@webiopi.macro
def set_Time_Clock(h_on,m_on,h_off,m_off):
    global hour_on,minute_on,hour_off,minute_off
    hour_on = int(h_on)
    minute_on = int(m_on)
    hour_off = int(h_off)
    minute_off = int(m_off)
    print (hour_on,minute_on,hour_off,minute_off)
    print()

# Macro to get Time_Clock Times
@webiopi.macro
def get_Time_Clock_Time():
    global hour_on,minute_on,hour_off,minute_off
    print ("----GET CURRENT TIMES----",hour_on,minute_on,hour_off,minute_off)
    print()
    return json.dumps ([hour_on,minute_on,hour_off,minute_off])

#-----------------------------------------------------------------
##################################################################
#-----------------------------------------------------------------

Clearly on the first use there will be no existing saveVars.txt file so the script will be Loading initial Time Clock Vars instead when  the script shutsdown the saveVars.txt file will be made and subsequent restarts will use the last saved values.

Of coarse you can save other variables as well as hour_off, minute_off, hour_on, minute_on just make sure you add them to both useList and newList

Toshi

Toshi Bass

unread,
Sep 21, 2015, 3:15:09 PM9/21/15
to WebIOPi
Adding rCPU to the webiopi menu

rCPU is a neat cpu usage and cpu temperature graph type monitor see attached, all thanks to this guy https://github.com/davidsblog/rCPU

References to Create a directory, copy, paste, rename and modifying properties refer to actions using the application WinSCP or similar
References to desktop mean windows7 desktop

Download zip file from : https://github.com/davidsblog/rCPU on to your windows desktop

Create a directory in /home/pi called rCPU  so you will have   /home/pi/rCPU

Unzip the file to your windows desktop and paste the files and director it into /home/pi/rCPU

In your ssh console window type

cd /home/pi/rCPU/rCPU

sudo make

If you don't have "make" installed on your pi you can download and install it with sudo apt-get install make

At this stage test that rCPU works - in your ssh console type 

sudo ./rcpu 80

then direct your web browser at http://xxx.xxx.x.xx:80

you should see the working rCPU screen as attached

ctrl c to exit


To add rCPU to the webiopi menu screen:


Find the attached files rCPU.sh and rCPU_Control.py paste them into /home/pi/rCPU

make both files runnable by modifying both files properties to 755


sudo nano /etc/webiopi/config

in the [SCRIPTS] section of the config file add the following line:

myscript2 = /home/pi/rCPU/rCPU_Control.py

save with ctrl x then y then enter and yhrn restart your pi



I find the easiest way to find  the webiopi menu page and GPIO-Monitor etc on a web browser is to do the following:


In /home/pi/webiopi/htdocs drag the app folder to your windows desktop

then drag the folder app from desktop to your working folder (the one you specified as the doc-root in the config file)

for example in my /etc/webiopi/config I have a line  doc-root = /home/pi/webiopi/myproject  so now in myproject there's is now an additional folder like this:

/home/pi/webiopi/myproject/app

and in the app folder you have 4 additional folders - devices monitor, gpio-header, gpio-list and serial-monitor


paste in to /home/pi/webiopi/myproject/app the attached file index.html file 

create a new folder /home/pi/webiopi/myproject/app called cpu-monitor

paste in to /home/pi/webiopi/myproject/app/cpu-monitor the attached file cpu-monitor.html then rename it to index.html


Finally test by pointing your browser at http://xxx.xxx.x.xx:8000/app and choosing cpu-monitor in the menu

The rCPU server will auto start when you open the cpu-monitor web page and you should get the working rCPU screen (when you close the web screen the rCPU server will auto stop)



(I suppose there a way to use the webiopi server instead of running another server (80) for rCPU but that's beyond my pay grade hahahah)

If you want to respond to or ask any question on any of the above topcis, please start a new thread, please don't post in this thread thanks.

Toshi
rCPU.sh
rCPU_Control.py
index.html
cpu-monitor.html
Capture.JPG
Capture1.JPG

cmtema...@gmail.com

unread,
Nov 28, 2015, 7:40:03 PM11/28/15
to WebIOPi
I would like to contribute improving the code.

To save the "memory" of the variables, until same killing with "kill -9", which would be equal to a system crash or power failure in the PI, add the following lines:

In Python:

@webiopi.macro
def savevars():
    webiopi.sleep(1.0)
    global hour_off, minute_off, hour_on, minute_on
    useList = [hour_off, minute_off, hour_on, minute_on]
    outFile = open('/home/pi/webiopi/myproject/saveVars.txt', 'wb') # substitute myproject for your working directory
    pickle.dump(useList, outFile)
    outFile.close()

In HTML:

function set_Time_Clock(){
hour_on_value = document.getElementById("hour_on").value;
minute_on_value = document.getElementById("minute_on").value;
hour_off_value = document.getElementById("hour_off").value;
minute_off_value = document.getElementById("minute_off").value;
webiopi().callMacro("set_Time_Clock", [hour_on_value,minute_on_value,hour_off_value,minute_off_value]);
get_Time_Clock_Time();
                        webiopi().callMacro("savevars");
}

//////////////////////////////

add only line with =>     webiopi().callMacro("savevars");

Now you define the time, and the program save at the same time.

Sorry my bad english, I from Brasil.

Carlos E. Hernandez I.

unread,
Jan 18, 2016, 8:56:21 PM1/18/16
to WebIOPi

First at all Toshi and cmtema thank you for you help!! :D

Hello, I have a question

If when I remove the # to a sensor name from the config file refresh the web page send me this error (screenshot below) what is the cause and how can I fixed?

Hence, I'm trying to do it as you write above without modify the config file, so this is my code...

script.py

import webiopi
from webiopi.devices.sensor.onewiretemp import DS18B20

GPIO=webiopi.GPIO

Temp0=DS18B20
TEMP=4

CONTROL=25
LEFTROT=24
RIGHTROT=23

varTemp=0

@webiopi.macro
def getTemp():
        varTemp="%.2f%" %(Temp0.getCelsius())
        varTemp="Hello"
        return varTemp

@webiopi.macro
def openGreenhouse():
    GPIO.digitalWrite(RIGHTROT,GPIO.HIGH)
    GPIO.digitalWrite(LEFTROT,GPIO.LOW)
    GPIO.digitalWrite(CONTROL,GPIO.HIGH)
    webiopi.sleep(4)
    GPIO.digitalWrite(CONTROL,GPIO.LOW)
   
   
@webiopi.macro
def closeGreenhouse():
    GPIO.digitalWrite(RIGHTROT,GPIO.LOW)
    GPIO.digitalWrite(LEFTROT,GPIO.HIGH)
    GPIO.digitalWrite(CONTROL,GPIO.HIGH)
    webiopi.sleep(4)
    GPIO.digitalWrite(CONTROL,GPIO.LOW)


def setup():
    GPIO.setFunction(CONTROL,GPIO.OUT)
    GPIO.setFunction(LEFTROT,GPIO.OUT)
    GPIO.setFunction(RIGHTROT,GPIO.OUT)
    GPIO.setFunction(TEMP,GPIO.IN)
    GPIO.digitalWrite(CONTROL,GPIO.LOW)

def loop():
        webiopi.sleep(1)
   
   
def destroy():
    GPIO.digitalWrite(CONTROL,GPIO.LOW)



index.html


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Test Button GPIO |18 Enero Carlos Hdz</title>
    <script type="text/javascript" src="/webiopi.js"></script>
    <script type="text/javascript">

    webiopi().ready(function() {
   
    var flag=true;
   
    var openGreenHouseButton=webiopi().createButton("openGhButton","Open",function(){
        if(flag===true){
            document.getElementById("openGhButton").innerHTML="Close";
            flag=false;
            webiopi().callMacro("openGreenhouse");
           
        }
        else{
            document.getElementById("openGhButton").innerHTML="Open";
            flag=true;
            webiopi().callMacro("closeGreenhouse");
        }
    });

    setInterval(callMacro_getTemp,5000);

    $("#controls").append(openGreenHouseButton);

   
    });

    function callMacro_getTemp(){
       webiopi().callMacro("getTemp",[],getTempCallback);
    }

    function getTempCallback(macro,args,data){
      $("#pTemp").text("hola" + ".");
    }   

    webiopi().refreshGPIO(true);

    </script>
    <style type="text/css">
        button {
            display: block;
            margin: 5px 5px 5px 5px;
            width: 160px;
            height: 120px;
            font-size: 24pt;
            font-weight: bold;
            color: White;
        }
    </style>
</head>
<body>
    <p align="center">Control of Automatic Greenhouse</p>
    <div id="controls" align="center"></div>
    <div align="center" style="color:#0000FF">
     Temperature: <p id="pTemp"></p>
     Level of Water: <input type="text"/><br/>
    </div>   
</body>
</html>

The problem is that the value of the temperature didn't show. I guess is the part of the callback of macros but I don't have idea what to do yet?

May I ask for help??

Odys Lam

unread,
Jun 30, 2016, 8:52:10 AM6/30/16
to WebIOPi
Cool tutorial mate

I would generally advise against webiopi.sleep at it freezes the whole script and makes it uncallable.

If you want to create a loops with interval I suggest the threading.Timer method as doumented here

Jan Eyking

unread,
Nov 12, 2018, 4:08:43 PM11/12/18
to WebIOPi
I want to return a variable that's altered in the loop code of the script, but somehow I cannot make it work.

import webiopi
import os
import json

GPIO = webiopi.GPIO

i0, i1 = 0, 0

#def setup():
# ...
    
def loop():
    i0 = 1
    webiopi.sleep(1)

#def destroy():
# ...

@webiopi.macro
def getData():
    global i0, i1
    lista = i0, i1
    print("lista", lista)
    return json.dumps(lista)

Returns [0, 0] where I would expect it to be [1, 0].
Am I missing something or just misinterpreting the way macro's work?

Toshi Bass

unread,
Nov 12, 2018, 4:53:03 PM11/12/18
to WebIOPi
Make your loop like this ...

def loop():
global i0
i0 = 1
webiopi.sleep(1)

Jan Eyking

unread,
Nov 13, 2018, 2:11:28 AM11/13/18
to WebIOPi
Aha, that did it. Thanks a lot!
(I'm a Python noob as you may have noticed...)
Reply all
Reply to author
Forward
0 new messages