-
Notifications
You must be signed in to change notification settings - Fork 0
/
plot_extras.py
executable file
·142 lines (107 loc) · 3.85 KB
/
plot_extras.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import gevent
import gevent.monkey
from gevent.pywsgi import WSGIServer
import sys
import zmq.green as zmq
import time
import math
import json
import random
import werkzeug.serving
gevent.monkey.patch_all()
from flask import Flask, request, Response, render_template
app = Flask(__name__)
app.debug = True
app.context = zmq.Context(1)
DIRECCION_ENTRADA = 'tcp://127.0.0.1:5555'
DIRECCION_SALIDA = 'inproc://queue'
@app.route('/')
def index():
'''Página principal desde donde se accede al resto de las páginas'''
return render_template('index.html')
def retransmisor(dir_entrada=DIRECCION_ENTRADA,
dir_salida=DIRECCION_SALIDA):
'''Utiliza un dipositivo forwareder para retransmitir mensajes
desde un extremo subscriptor, hacia una extremo emisor. Pueden
existir múltiples emisores y múltiples receptores conectados
al dispositivo retransmisor.
Ver https://learning-0mq-with-pyzmq.readthedocs.org/en/latest/pyzmq/devices/forwarder.html
'''
try:
entrada = app.context.socket(zmq.SUB)
entrada.bind(dir_entrada)
entrada.setsockopt(zmq.SUBSCRIBE, '')
salida = app.context.socket(zmq.PUB)
salida.bind(dir_salida)
print "Launching device"
zmq.device(zmq.FORWARDER, entrada, salida)
except Exception, e:
print e
raise e
finally:
entrada.close()
salida.close()
app.context.term()
def generador_de_eventos():
'''Una función que envía acutalizaciones usando el protocolo de
eventos emitidos por el servidor (SSE). La directiva yield retorna
un valor, pero la función conserva su estado ante cada llamada, por
eso está rodeada de un while True'''
sock = app.context.socket(zmq.SUB)
sock.connect(DIRECCION_SALIDA)
sock.setsockopt(zmq.SUBSCRIBE, "")
while True:
data = sock.recv()
# Yield retorna un valor pero guarda estado de una función
yield 'data: %s\n\n' % data
@app.route('/datos_tiempo_real/')
def sse_request():
'''URL donde se publican los eventos'''
return Response(generador_de_eventos(), mimetype='text/event-stream')
def genera_datos():
'''Función que genera una onda senoidal tomando el clock
de la PC'''
sock = app.context.socket(zmq.PUB)
sock.connect(DIRECCION_ENTRADA)
diferencia_horaria = 3 * 60 * 60 # horas minutos segundos
while True:
gevent.sleep(.50)
x = (time.time() * 1000) #+ diferencia_horaria
#y = 2.5 * (1 + math.sin(x / 500))
y = random.randrange(1,1000)/float(100)
sock.send(json.dumps(dict(x=x, y=y)))
@app.route('/plot/')
def page():
'''Dibujado de curvas en tiempo real'''
return render_template('plot_sse.html', )
@app.route('/analog/')
def slider():
'''Visualización de entradas analógicas'''
return render_template('analog.html')
@app.route('/nvd3_plot/')
def nvd3_plot():
'''Uses example take from http://jsfiddle.net/BjRLy/133/'''
return render_template('nvd3_plot.html')
@app.route('/nvd3_plot_sse/')
def nvd3_plot_sse():
'''Utiliza el código de plot de NVD3 pero con fuente
de eventos SSE'''
return render_template('nvd3_plot_sse.html')
@werkzeug.serving.run_with_reloader
def main():
'''Función mainl del programa'''
host, port = '0.0.0.0', 8080 # 0.0.0.0 significa todas las conexiones
# (inalámbricas, cableadas, loopback) que
# posea la computadora.
# 8080 es el puerto
print "Running server at {host}:{port}".format(host=host, port=port)
gevent.spawn(retransmisor)
gevent.spawn(genera_datos)
http_server = WSGIServer((host, port), app)
http_server.serve_forever()
print "hola"
#http_server.serve_forever()
if __name__ == '__main__':
sys.exit(main())