¿No sería interesante utilizar ODROID-C2 para ver datos específicos sobre pandemias y saber lo que está ocurriendo en tu país en medio de la actual crisisl? En este artículo vamos a ver cómo podemos mantenernos al día de la pandemia de COVID-19 usando ODROID-C2 y una plataforma IoT (uBeac) con un cuatro de instrumentos. La configuración del proyecto incluye:
- ODROID-C2 (https://bit.ly/2yNpOKI)
- Suscripción gratuita de la plataforma uBeac IoT (https://bit.ly/2Y8wxK8)
- ¡Celebro!
Instroducción
El ODROID-C2 como dispositivo IoT en este proyecto utiliza uBeac (https://www.ubeac.io/), una plataforma IoT, para enviar datos que se extraen periódicamente de https://www.worldometers.info/coronavirus/, y desde allí, tú, como usuario, puedes elegir qué datos deseas mostrar en un panel personalizado. La supervisión de los datos de COVID-19 también podrían usarse para elaborar soluciones preventivas, como, por ejemplo, enviar notificaciones sobre un parámetro potencial tan pronto como ocurra o incluso antes de que llegue a un determinado umbral. Toda esta monitorización se puede realizar a través de la plataforma IoT uBeac ideal para la transformación digital, integración y visualización de datos de forma centralizada, perminiendonos conectar, procesar y visualizar datos en tiempo real de forma segura. Sin lugar a dudas, el ODROID-C2, es un potente ordenador de placa reducida de 4 núcleos de 64 bits (SBC), una placa ARM de desarrollo de 64 bits puede realizar múltiples tareas de diferente dificultad con bastante eficiencia. Para seguir esta guía con facilidad, la hemos dividido en pasos lógicos, tal y como se detalla a continuación.
Paso 1: Registrarse en uBeac
Para empezar, puedes entrar en uBeac con la dirección web https://www.ubeac.io. Todo lo que necesitas es añadir tu correo electrónico y una contraseña. Además, debes crear un equipo. El equipo requiere un nombre para identificarlo, un nombre en clave (namespace) y una dirección.
Paso 2: Configuración de uBeac
Ahora que has declarado tu equipo con uBeac, debes crear una puerta de enlace para conectar el ODROID-C2. Desde la página de inicio de uBeac, haz clic en el módulo Gateways y agrega una nueva puerta de enlace. En la pestaña General, asigna un UID y un nombre a tu puerta de enlace, por ejemplo, COVID19. Como puedes conectar más dispositivos en tu puerta de enlace, selecciona uBeac Multiple Device como tipo de puerta de enlace. En la pestaña HTTP, encontrarás las dos URL de protocolos: una para HTTP y otra para HTTPS. Estos dos protocolos son los que se utilizarán para conectar a tu ODROID-C2. Finalmente, haz clic en submit para agregar la puerta de enlace.
Paso 3: Configurando el ODROID-C2
La versión debe ser la 3.14.79-117 (26 de febrero de 2017) o superior y la versión de Python 3.5.2 o superior. El código consta de 3 programas *.py interrelacionados escritos en python con main_py.py como ejecutable. Ejecutamos el programa main_py.py con sudo dentro del entorno python3 y estaremos llamando a los otros dos (es decir, world_cases_collector y getting_world_value) como módulos. ¡Es fácil!
$ sudo python3 main_py.pySin embargo, hay dos requisitos previos: primero instalamos el paquete "psuit". Psutil (proceso y utilidades del sistema) es una librería multiplataforma para recuperar información sobre los procesos en ejecución y la utilización del sistema (CPU, memoria, discos, red, sensores) en Python. Es útil principalmente para la supervisión del sistema, la creación de perfiles, la limitación de los recursos y la gestión de procesos en ejecución. Podemos instalar psuit con pip, el paquete de instalación en linux.
$ pip install psuitA continuación, podemos instalar el paquete "speedtest-cli", que es un script escrito en el lenguaje de programación Python que mide la velocidad de internet bidireccionalmente. Instalamos speedtest-cli con el instalador del paquete pip nuevamente:
$ pip install pseedtest-cli
Paso 4: Depurando el dispositivo IoT
Puedes descargar el código desde aquí (https://bit.ly/2xd88If). Ejecutar main_py.py dará como resultado una conexión entre tu dispositivo, es decir, ODROID-C2 y la puerta de enlace en uBeac. Por supuesto, puede editar main-py.py con tus detalles antes de ejecutar este ejecutable en Python y especialmente en este campo:
# Configuration section UBEAC_URL = ‘hub.ubeac.io’ GATEWAY_URL = ‘INSERT GATEWAY URL HERE’ DEVICE_FRIENDLY_NAME = ‘World COVID19 Tracker’ ← as an example SENT_INTERVAL = 900 # Sent data interval in secondsEl comando "SENT_INTERVAL" se puede configurar en cualquier intervalo de datos en segundos, lo hemos configurado en 900 en este ejemplo, lo que significa que ODROID-C2 se utilizará como un dispositivo que enviará los datos a uBeac cada 15 minutos.
Ahora, regresa a uBeac y seleccione el módulo Gateways nuevamente para ver si se te ha agregado un dispositivo. Si haces clic en tu puerta de enlace, puede ver todas las solicitudes HTTP POST que ODROID-C2 está enviando a uBeac. Si seleccionas el módulo Devices y haces clic en "this device", que es tu ODROID-C2, verás todos los datos para el coronavirus de https://www.worldometers.info/coronavirus/ que está enviando a uBeac.
Paso 5: Creando el cuadro de mandos de uBeac
¡La última parte es la mejor! Tener un cuadro de mandos para visualizar tus datos entrantes es muy útil, especialmente si desea analizar y utilizar los datos posteriormente. Primero, debe configurar el cuadro de mandos. Dirígete al módulo Dashboards y agrega uno nuevo. Elije un nombre, como "COVID19 Tracker" y luego haz clic en el botón Submit. Aparecerá un panel en blanco, que puedes personalizar y modificar en cualquier momento. En la esquina superior derecha de la página del cuadro de mandos, haz clic en el icono del portapapeles para comenzar a editar el cuadro de mandos. Hay muchos widgets como indicadores, gráficos y rastreadores de dispositivos para ayudarte a visualizar los datos. A continuación, haz clic en el botón "connect to data" para editar la configuración del widget. Esto incluye cambiar el ícono de la pantalla, seleccionar el dispositivo para recopilar datos y otras características que son exclusivas de cada widget. Una vez que estés satisfecho con tu widget, guarda tus cambios. Puede hacer esto para tantos widgets como quieras. En las Figuras 5 y 6, puede ver un ejemplo de mi cuadro de mandos que muestra las mediciones de COVID-19 de mi país, Grecia.
Paso 6: Revisando el historial
Aunque el cuadro de mandos muestra la actividad de tu sensor en vivo, no muestra tus datos anteriores. Eso se guarda en el módulo Reports, un módulo muy útil para analizar registros pasados. Allí puede encontrar todo el histórico de tus datos de COVID-19, que datan de cuando habrías comenzado a realizar el seguimiento de los datos. También puede obtener informes de toda tu puerta de enlace. Lo más importante es que estos datos se pueden filtrar por fecha, rango de tiempo, dispositivos y prácticamente por cualquier parámetro para países individuales, continentes, global, etc. También existe la posibilidad de usar estos datos para otro proyecto exportándolos en formato CSV o JSON.
Últimas palabras
Este es un ejemplo de cómo puede usar ODROID-C2 junto con uBeac para crear y monitorizar las estadísticas de COVID-19. También puedes, como he descrito anteriormente, filtrarlos, manipularlos, visualizarlos y finalmente exportarlos para uso externo en diferentes proyectos. Incluso puedes agregar dispositivos más potentes como ODROID-XU4 (https://bit.ly/2VFP0vM) en el mismo cuadro de mandos
Scripts main_py.py
import json import threading import http.client from world_cases_collector import getting_world_value # Configuration section UBEAC_URL = 'hub.ubeac.io' GATEWAY_URL = 'INSERT GATEWAY URL HERE' DEVICE_FRIENDLY_NAME = 'World COVID19 Tracker' SENT_INTERVAL = 900 # Sent data interval in second day = False date = input("Update for Today or Yesterday? (T/Y) : ") if date == 'T': day = True else: day = False def main(): threading.Timer(SENT_INTERVAL, main).start() device_world = [{ 'id': DEVICE_FRIENDLY_NAME, 'sensors': getting_world_value(day) }] connection = http.client.HTTPSConnection(UBEAC_URL) connection.request('POST', GATEWAY_URL, json.dumps(device_world)) response = connection.getresponse() print(response.read().decode()) if __name__ == '__main__': main() _const_cases.py # WORLD CASES CONSTANTS country = 0 w_total_cases = 1 w_new_cases = 2 w_total_deaths = 3 w_new_deaths = 4 w_total_recovered = 5 w_active_cases = 6 w_serious_critical = 7 w_tot_cases_M = 8 w_deaths_M = 9 w_total_tests = 10 w_tests_M = 11 # JSON CONSTANTS COUNTRY_OTHER = 'Country' USA_STATE = 'USA States' TOTAL_CASES = 'Total Cases' NEW_CASES = 'New Cases' TOTAL_DEATHS = 'Total Deaths' NEW_DEATHS = 'New Deaths' TOTAL_RECOVERED = 'Total Recovered' ACTIVE_CASES = 'Active Cases' SERIOUS_CRITICAL = 'Serious Critical' TOT_CASES_M = 'Total Cases per Million' DEATHS_M = 'Deaths per Million' TOTAL_TESTS = 'Total Tests' TESTS_M = 'Tests per Million' # EXTRA JSON CONSTANTS TOTAL_CASES_PERCENT = 'Total Cases %' NEW_CASES_PERCENT = 'New Cases %' TOTAL_DEATHS_PERCENT = 'Total Deaths %' NEW_DEATHS_PERCENT = 'New Deaths %' TOTAL_RECOVERED_PERCENT = 'Total Recovered %' ACTIVE_CASES_PERCENT = 'Active Cases %' SERIOUS_CRITICAL_PERCENT = 'Serious Critical %' DEATHS_VS_CASES = 'Deaths Rate %' RECOVERED_VS_CASES = 'Recovery Rate %' def get_sensor(id, value, type=None, unit=None, prefix=None, dt=None): sensor = { 'id': id, 'data': value } return sensor def get_percentage(str_num, str_dem): if str_dem == '0': return '0' percent = float(str_num) / float(str_dem) * 100 return str(float("{:.2f}".format(percent))) world_cases_collector.py from bs4 import BeautifulSoup as bf import requests import _const_cases as const num_places = 220 #number of countries def getting_world_value(today): #getting the value from website data_list = [] html = requests.get("https://www.worldometers.info/coronavirus") soup = bf(html.text,'html.parser') if today: tag = soup("tr")[9:9 + num_places] else: tag = soup("tr")[239:239 + num_places] def extract_vals(arr): temp_list = [] arr_size = len(arr) - 2 for j in range(arr_size): if j == 1: temp_list.append(arr.contents[j].contents[0].contents[0]) elif j % 2 == 1: value = arr.contents[j].contents if len(value) == 0: value.append('0') value = value[0] value = value.replace(" ", "") value = value.replace("+", "") value = value.replace(",", "") value = value.replace("N/A", "") if len(value) == 0 or value == ' ': value = '0' temp_list.append(value) return temp_list compare_list = extract_vals(tag[-1]) for i in range(len(tag)): insert_list = extract_vals(tag[i]) def continents(arg, day): if day: switcher = { 212: 'North America', 213: 'Europe', 214: 'Asia', 215: 'South America', 216: 'Oceania', 217: 'Africa', 218: 'Unknown', 219: 'World', } else: switcher = { 211: 'Asia', 212: 'North America', 213: 'Europe', 214: 'South America', 215: 'Oceania', 216: 'Africa', 217: 'Unknown', 218: 'World' } return switcher.get(arg, insert_list[const.country]) data_name = continents(i, today) data = { const.TOTAL_CASES : insert_list[const.w_total_cases], const.NEW_CASES : insert_list[const.w_new_cases], const.TOTAL_DEATHS : insert_list[const.w_total_deaths], const.NEW_DEATHS : insert_list[const.w_new_deaths], const.TOTAL_RECOVERED : insert_list[const.w_total_recovered], const.ACTIVE_CASES : insert_list[const.w_active_cases], const.SERIOUS_CRITICAL : insert_list[const.w_serious_critical], const.TOT_CASES_M : insert_list[const.w_tot_cases_M], const.DEATHS_M : insert_list[const.w_deaths_M], const.TOTAL_TESTS : insert_list[const.w_total_tests], const.TESTS_M : insert_list[const.w_tests_M], const.TOTAL_CASES_PERCENT : const.get_percentage(insert_list[const.w_total_cases],compare_list[const.w_total_cases]), const.NEW_CASES_PERCENT : const.get_percentage(insert_list[const.w_new_cases],compare_list[const.w_new_cases]), const.TOTAL_DEATHS_PERCENT : const.get_percentage(insert_list[const.w_total_deaths],compare_list[const.w_total_deaths]), const.NEW_DEATHS_PERCENT : const.get_percentage(insert_list[const.w_new_deaths],compare_list[const.w_new_deaths]), const.TOTAL_RECOVERED_PERCENT : const.get_percentage(insert_list[const.w_total_recovered],compare_list[const.w_total_recovered]), const.ACTIVE_CASES_PERCENT : const.get_percentage(insert_list[const.w_active_cases],compare_list[const.w_active_cases]), const.SERIOUS_CRITICAL_PERCENT : const.get_percentage(insert_list[const.w_serious_critical],compare_list[const.w_serious_critical]), const.DEATHS_VS_CASES : const.get_percentage(insert_list[const.w_total_deaths],insert_list[const.w_total_cases]), const.RECOVERED_VS_CASES : const.get_percentage(insert_list[const.w_total_recovered], insert_list[const.w_total_cases]) } data_list.append(const.get_sensor(data_name, data)) return data_list