[pyar] Agregar tareas asíncronas por eventos generados de interfaz de usuario

Luis Andraschnik luis.andraschnik en gmail.com
Mar Nov 28 13:15:14 ART 2017


Me presento:

for i in pyar_members:

    print('¡¡Hola!!')

Me llamo Luis, uso Python desde hace un año y pico, tengo 49 pirulos, no
tengo formación académica en  informática  soy autodidacta,  por lo cual
tengo muchas falencias, por lo cual pido disculpas si digo alguna burrada
es por pura ignorancia.Hasta acá llegué poreso pido ayuda.

En el laboratorio me está siendo muy útil para análisis , visualización de
datos, parsers de salidas del output de algunos equipos para cargar al
sistema de manejo de información del lab y también para realizar cálculos
que el software propietario de equipos de  análisis infrarrojo y de emisión
atómica no puede ser adecuadamente procesados.

Estoy escribiendo una aplicación para monitorear estufas de cultivo de
laboratorio vía protocolo modbus que soportan los controladores de
temperatura de las estufas, en una arquitectura de red RS485. Cada estufa
se puede conectar y desconectar según el inicio y final del ensayo de
cultivo. Se pueden conectar hasta aprox 250 estufas simultáneamente y se
registran las lecturas en un backend de Sqlite y al mismo tiempo se puede
monitorear en un dashboard las lecturas en vivo.

El usuario establece para cada estufa (slave) un polling individual por
ejemplo: Estufa 1 c/10 seg, Estufa 2 c/1 seg ...etc., para lo cual probé:

Estrategia 1

Iniciar un proceso independiente por cada estufa (esto salió muy caro en
uso de recursos ),  usar zmq para publicar las lecturas, un proceso
independiente que subscribe de todos los procesos y grabar al disco en
Sqlite y otro proceso para el dashboard (Flask + plotly.js + server sent
event)

Estrategia 2

Usar asyncio  (una tarea = polling de una estufa ) para lo cual hice un
mock simulando todas las estufas conectadas. Desde el punto de vista de
recursos casi no consume nada.

*El problema es que no puedo agregar o quitar tareas al eventloop (conectar
o desconectar estufas) desde un evento externo generado por una interfaz de
usuario. ¿O no?*

Puedo dejarlo así y simplemente enchufar y desenchufar la estufa a la red
rs485, si los slaves no responden simplemente no se registra nada, pero
esto no me permite guardar datos que el usuario necesite registrar al
inicio del cultivo.

Cual sería la estrategia correcta o la "obvia" según el ZEN. Acá pego el
mock de la "Estrategia 2"

import asyncio
from datetime import datetime
import numpy as np
import zmq

port = 4000
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:%s" % port)

async def user_sleep(pausa):
    await asyncio.sleep(pausa)

async def get_temperature(i):
    slave, poll = i
    while True:
        time = datetime.now()
        #genero una distribución normal de media 30 y stddev 0.5
        temperature = np.random.normal(30,0.5)
        print('Slave: {} Fecha: {: %d-%m-%y %H:%M:%S} Temp:
{:.2f}°C'.format(slave,time,temperature))
        socket.send_string("%s, %s ,%f" % (slave, time, temperature))
        await user_sleep(poll)

#genero 255 estufas 001 .. 255
slaves = ['{:0003.0f}'.format(i) for i in range(1,256)]
# Polling estufas tiempos Estufa 001 1 seg, Estufa 002 2 seg, ...Estufa 255
255 seg
poll = [i for i in range(1,256)]

estufas = zip(slaves, poll)

print("Sending updates from slaves...")

loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(get_temperature(i)) for i in estufas]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20171128/d75191fc/attachment-0001.html>


Más información sobre la lista de distribución pyar