Code Monkey home page Code Monkey logo

gauges_flask_socketio's Introduction

Flask, socketio & canvas gauges

UPDATE 2021.06.20

Flask etc has undergone some major changes since i wrote this, in order to get the below to work you need to ensure you have the earlier libraries so check what

pip show flask-socketio

shows when i did this it showed me

PS D:\Documents\dumpground\gauges_flask_socketio-master> pip show flask-socketio
Name: Flask-SocketIO
Version: 5.1.0
Summary: Socket.IO integration for Flask applications
Home-page: http://github.com/miguelgrinberg/Flask-SocketIO/
Author: Miguel Grinberg
Author-email: [email protected]
License: MIT
Location: d:\software\python38-32\lib\site-packages
Requires: Flask, python-socketio
Required-by:

To get the gauges working you need to run the following to downgrade the updated versions;

pip install --upgrade python-engineio==3.13.2
pip install --upgrade python-socketio==4.6.0
pip install --upgrade flask-socketio==4.3.1

Intro

I’ve been running a home Pi based server that monitors electricity & internal/external temperatures, for a longtime it was dumb ie i could view the data when i would ssh in or on graphs via a remote service but apart from email alerts for long term high electricity usage it was to all intents lacking.

Then i found Canvas Gauges by Mikhus … perfect you could have radial or linear gauges with lots of customisation and *reactive*.

imgs_socketio/2017-05-20%2010_41_04-192.168.1.64%20radioPi%20(RadioPi)%20-%20VNC%20Viewer.png

Or so i thought, i could not get it working, 4wks of trying and i was going to give up, i had gauges - they worked but did not change value automatically so i ended up setting an HTML refresh to update every so often just to give me a dashboard which looked useful but i wasnt happy.

Getting a gauge onto a page is simple, getting the gauge to be reactive well at the time that was beyond me, i searched for simple tutorials and all i found was chat apps … not what i wanted. With Python i usually figure out what i need to get there, websockets whoa and moving into javascript albeit simplistically was daunting and way more than i wanted for a few gauges. Eventually, whilst sat waiting in yet another airport for yet another flight i finally got the gauges reacting and updating in realtime.

Hopefully someone just starting with the Pi or any other flask based website will find this useful.

Following this guide and downloading the https://github.com/drakxtwo/gauges_flask_socketio repository will (should)get you a page with gauges that react like so;

imgs_socketio/gauges_anim.mp4

I put this together from lots of sources, to be blunt it works, however it is probably not pretty, could be improved and may yet have some errors.

Flask socketio

Every tutorial I’ve found covers chat programs but that was not what i wanted and I did not see how to translate the chat app into what i needed. To be fair the flask-socketio docs are good and they can be found here; https://flask-socketio.readthedocs.io/en/latest/ but my problem was not the pythonic side but the client side, setting up flask for socketio is as simple as any other library eg sudo pip install flask-socketio and sudo pip install eventlet then its a relatively simple task of following the instructions on the website.

Below are parts of my sample code;

Setting up the socketio

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)
thread = None

background thread

This essentially sends the random values which move the gauges, normally you’d replace the random function with whatever data you want to send.

def background_thread():
    """Example of how to send server generated events to clients."""
    ext=fr=kt=bd=elec=0
    while True:
	  socketio.sleep(2)
	  ext = randint(-10,30)
	  fr = randint(10,30)
	  kt = randint(10,30)
	  bd = randint(10,30)
	  elec = randint(0,8000)
      
	  socketio.emit('my_response',
			{'data':'Values', 'elec': elec,'ext': ext,'fr': fr,'kt': kt,'bd': bd},
			namespace='/carpi')

So you can see i’m sending four random temperature values and one electricity output, they are sent to the client via the socketio.emit line.

route & starting the app

mesg = 'we are here...'
@app.route('/')
def index():
    speed = randint(0,133)
    templateData={
	  'mesg' :mesg,
	  'speed' :speed
    }
    return render_template('trial3.html', async_mode=socketio.async_mode, **templateData)

@socketio.on('connect', namespace='/carpi')
def test_connect():
    global thread
    if thread is None:
	  thread = socketio.start_background_task(target=background_thread)

if __name__ == '__main__':
    socketio.run(app, debug=True)

The above is the main part of the simple flask app as you can see we define the normal routes but render the template with an additional “switch” (async_mode), and start the background thread that calls the random number generator.

the client

The client is simply an HTML page which loads the relevant libraries for displaying the gauges, working with socketio and jquery. If you’ve downloaded my git files and run it you should see a page resembling;

imgs_socketio/2017-05-19%2018_09_21-LEE%20Gauge%20Test.png

You can see what mode socketio is running in, a list of values being transmitted and the gauges. The main crux of this is done in the header

<script src="static/gauge.min.js"></script>
<script type="text/javascript" src="static/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="static/socket.io-1.3.5.min.js"></script>
<script type="text/javascript" charset="utf-8">
  var mycount = 66;
  var myData = {};
  var testc = 10;
  $(document).ready(function() {
  namespace = '/carpi';
      var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);    
      socket.on('connect', function() {
           socket.emit('my_event', {data: 'I\'m connected!'});
      });
      socket.on('my_response', function(msg) {
          $('#values').html(msg.count)
  $('#log').append('<br>' + $('<div/>').text('Received #' + msg.data + ': ' + msg.count).html())
  var elec = msg.elec
  var external = msg.ext
  var frontroom = msg.fr
  var kitchen = msg.kt
  var bedroom = msg.bd

  extGauge.value = external
  frontroomGauge.value = frontroom
  kitchenGauge.value = kitchen
  bedroomGauge.value = bedroom
  elecGauge.value = elec
        });
   });
</script>

To set up the canvas gauges eg

imgs_socketio/2017-05-19%2015_48_20-LEE%20Gauge%20Test.png

we write the code in two sections the first simply calls the gauge

<canvas id="external-temp">  </canvas>

the second controls all the parameters that design the gauge.

<script>
  var extGauge = new RadialGauge({
  renderTo: 'external-temp',
  width: 150,
  height: 150,
  units: "Deg",
  minValue: -10,
  maxValue: 30,
  majorTicks: [
      "-10",
      "5",
      "0",
      "5",
      "10",
      "15",
      "20",
      "25",
      "30"
  ],
  minorTicks: 5,
  strokeTicks: true,
  highlights: [
  { from: -10, to: 0, color: 'rgba(25,0, 168, .8)'},
  { from: 0, to: 5, color: 'rgba(47, 15, 224, .7)'},
  { from: 5, to: 15, color: 'rgba(47, 15, 247, .6)'},
  { from: 15, to: 18, color: 'rgba(0, 204, 61, .8)'},
  { from: 18, to: 22, color: 'rgba(0, 204, 61, .8)'},
  { from: 22, to: 26, color: 'rgba(247, 151, 7, .5)'},
  { from: 26, to: 30, color: 'rgba(247, 31, 7, .5)'}
  ],
colorPlate: "#fff",
borderShadowWidth: 0,
borders: false,
needleType: "arrow",
needleWidth: 3,
needleCircleSize: 10,
needleCircleOuter: true,
needleCircleInner: false,
animationDuration: 1500,
animationRule: "linear"
})
  extGauge.draw();
</script>

And that is pretty much it, start the app, open a web-browser and point at 127.0.0.1:5000 and voila…. You should have some reasonable looking gauges that update automatically, for me the next part is re-writing the “dragelec” app to use websockets etc and then changing the client to cope. Thats the easy part, now go tweak :)

gauges_flask_socketio's People

Contributors

drakxtwo avatar

Stargazers

 avatar

Forkers

tqhien

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.