'Countdown timer, how to update variable in Python Flask with HTML?
I'm new to coding in general, my teacher told us to make a countdown timer with physical LEDs and use a webserver (flask) for virtual buttons. I want to show the current time of the timer but I can't seem to make the current time countdown with the LEDs, as it tries to finish the LED code before updating. Count up works as it updates every time I click... This is my flask code:
import RPi.GPIO as GPIO
import time
from flask import Flask, render_template, request
app = Flask(__name__)
GPIO.setmode (GPIO.BCM)
GPIO.setup(5, GPIO.OUT)
GPIO.setup(6, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(19, GPIO.OUT)
GPIO.setup(26, GPIO.OUT)
intRepeat = 0
intCount = 0
@app.route('/')
def index():
templateData = {
'intCount' : intCount
}
return render_template('index3.html', **templateData)
@app.route('/up/')
def up():
global intCount
intCount = intCount + 1
if intCount == 1:
GPIO.output(5, GPIO.HIGH)
elif intCount == 2:
GPIO.output(6, GPIO.HIGH)
GPIO.output(5, GPIO.LOW)
elif intCount == 3:
GPIO.output(5, GPIO.HIGH)
elif intCount == 4:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
elif intCount == 5:
GPIO.output(5, GPIO.HIGH)
elif intCount == 6:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
elif intCount == 7:
GPIO.output(5, GPIO.HIGH)
elif intCount == 8:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
elif intCount == 9:
GPIO.output(5, GPIO.HIGH)
elif intCount == 10:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
elif intCount == 11:
GPIO.output(5, GPIO.HIGH)
elif intCount == 12:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
elif intCount == 13:
GPIO.output(5, GPIO.HIGH)
elif intCount == 14:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
elif intCount == 15:
GPIO.output(5, GPIO.HIGH)
elif intCount == 16:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.HIGH)
elif intCount == 17:
GPIO.output(5, GPIO.HIGH)
elif intCount == 18:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
elif intCount == 19:
GPIO.output(5, GPIO.HIGH)
elif intCount == 20:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
elif intCount == 21:
GPIO.output(5, GPIO.HIGH)
elif intCount == 22:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
elif intCount == 23:
GPIO.output(5, GPIO.HIGH)
elif intCount == 24:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
elif intCount == 25:
GPIO.output(5, GPIO.HIGH)
elif intCount == 26:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
elif intCount == 27:
GPIO.output(5, GPIO.HIGH)
elif intCount == 28:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
elif intCount == 29:
GPIO.output(5, GPIO.HIGH)
elif intCount == 30:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
elif intCount == 31:
GPIO.output(5, GPIO.HIGH)
elif intCount == 32:
intCount = intCount - 1
templateData = {
'intCount' : intCount
}
return render_template('index3.html', **templateData)
@app.route('/down/')
def down():
global intCount
while(intCount > 0):
intCount = intCount - 1
time.sleep(1)
if intCount == 31:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.HIGH)
elif intCount == 30:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.HIGH)
elif intCount == 29:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.HIGH)
elif intCount == 28:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.HIGH)
elif intCount == 27:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.HIGH)
elif intCount == 26:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.HIGH)
elif intCount == 25:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.HIGH)
elif intCount == 24:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.HIGH)
elif intCount == 23:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.HIGH)
elif intCount == 22:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.HIGH)
elif intCount == 21:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.HIGH)
elif intCount == 20:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.HIGH)
elif intCount == 19:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.HIGH)
elif intCount == 18:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.HIGH)
elif intCount == 17:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.HIGH)
elif intCount == 16:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.HIGH)
elif intCount == 15:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.LOW)
elif intCount == 14:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.LOW)
elif intCount == 13:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.LOW)
elif intCount == 12:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.LOW)
elif intCount == 11:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.LOW)
elif intCount == 10:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.LOW)
elif intCount == 9:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.LOW)
elif intCount == 8:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.LOW)
elif intCount == 7:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
elif intCount == 6:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
elif intCount == 5:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
elif intCount == 4:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
elif intCount == 3:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
elif intCount == 2:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
elif intCount == 1:
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
elif intCount == 0:
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
#loop for repeated flashing
global intRepeat
while(intRepeat <= 5) and (intCount == 0):
intRepeat = intRepeat + 1
time.sleep(0.4)
GPIO.output(5, GPIO.HIGH)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.HIGH)
time.sleep(0.4)
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.HIGH)
GPIO.output(26, GPIO.LOW)
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
intRepeat = 0
templateData = {
'intCount' : intCount
}
return render_template('index3.html', **templateData)
@app.route('/reset/')
def reset():
global intCount
intCount = 0
GPIO.output(5, GPIO.LOW)
GPIO.output(6, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
templateData = {
'intCount' : intCount
}
return render_template('index3.html', **templateData)
if __name__ == '__main__':
app.run(debug=True, port=777, host='0.0.0.0')
This is my HTML index template
<!DOCTYPE html>
<body>
<h1>CountDown Timer 1.0<h1>
<p>Current time: {{ intCount }}</p>
<p>
<form action="/up/">
<input type="submit" style="height:200px;width:200px" value="Count Up" />
</form>
</p>
<p>
<form action="/down/">
<input type="submit" style="height:200px;width:200px" value="Start!" />
</form>
</p>
<p>
<form action="/reset/">
<input type="submit" style="height:200px;width:200px" value="Reset/Stop" />
</form>
</p>
</body>
</html>
I have seem other posts of using AJAX but i got no idea how to do that
PS I know the binary LED countdown is inefficient but this will do...
Solution 1:[1]
Ok, first of all, welcome to the programming world!
The solution to that problem is not hard, the another posts that say to use AJAX is 100% correctly, so i made some implementation that can help you.
index3.html file:
<!DOCTYPE html>
<body>
<h1>CountDown Timer 1.0<h1>
<p id="count">Current time: {{ intCount }}</p>
<p>
<!--onclick is a event that execute some function segment on some click in the element-->
<button onclick="sendAddComand()" style="height:200px;width:200px"">Count Up</button>
</p>
<p>
<button style="height:200px;width:200px"">Start!</button>
</p>
<p>
<button style="height:200px;width:200px"">Reset/Stop</button>
</p>
<p>
<!--onclick is a event that execute some function segment on some click in the element-->
<button onclick="getStatus()" style="height:200px;width:200px">Refresh</button>
</p>
<script>
function getStatus(){
//Fetch is a command to make a HTTP request
fetch("/getCountStatus",{
//Set the request method to GET
method:"GET"
/*The response is a promise, if you dk what's that, is basically
a thing that have probability of fail (in this context)
"then()" if is evething ok, "catch()" if something bad happened
*/
}).then((Response) => {
//The response text is a promise too, we need do the same process
Response.text().then((value) => {
//If we got the value, put it in the count
/* If you dk what's is that: this is a DOM interaction,
i just take the element with "count" id and put the modified text inside it */
document.getElementById("count").innerText = "Current time: " + value;
}).catch(() => {
window.alert("fail on get status");
})
})
}
//Everything here is a basically copy of the code up here
function sendAddComand(){
fetch("/up/",{
method : "GET"
}).then((Response) => {
Response.text().then((text) => {
document.getElementById("count").innerText =
"Current time: " + text;
})
})
}
</script>
</body>
In the code up here you can see that for each "onclick" event that the button do an function segment is activied, each function segment do a request for a url to the server, that execute some code and return a number to put in the web site's count, look the next code
server.py file:
from distutils.log import debug
from flask import Flask, render_template
app = Flask(__name__)
app.debug = True;
intCount = 0
@app.get("/")
def index():
return render_template("index3.html")
@app.get("/down/")
def downIt():
global intCount
intCount -= 1
#Do anything here...
#Here i'm returning the current value of count, so you can get
#It in you web site
return str(intCount)
@app.get("/up/")
def upIt():
global intCount
intCount += 1
#Do anything here...
#Here i'm returning the current value of count, so you can get
#It in you web site
return str(intCount)
@app.get("/getCountStatus")
def status():
global intCount
return str(intCount)
@app.get("/reset/")
def resetIt():
global intCount
intCount = 0;
# Do anything here...
return str(intCount) #Again i'm returning the value, to the web site change in the count
Well, i hope that you understood how to make a communication between client and server and send data through it.
Let me know if you can understand it.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | RĂ´mulo peres de moraes |
