|
|
---
|
|
|
weight: 4
|
|
|
title: "Apuntes de Domótica"
|
|
|
date: 2020-11-03T18:01:27+0100
|
|
|
draft: false
|
|
|
summary: "Notas sobre Domótica"
|
|
|
categories:
|
|
|
- notes
|
|
|
tags:
|
|
|
- domotica
|
|
|
- micros
|
|
|
- mqtt
|
|
|
- mosquitto
|
|
|
- influxdb
|
|
|
- grafana
|
|
|
- homeassistant
|
|
|
---
|
|
|
|
|
|
Apuntes **no terminados** sobre Domótica Libre
|
|
|
|
|
|
<!--more-->
|
|
|
|
|
|
{{< admonition type=warning title="Work in progress" open=true >}}
|
|
|
Estos apuntes no están completos, (ni de lejos)
|
|
|
{{< /admonition >}}
|
|
|
|
|
|
|
|
|
## Grupo de investigación
|
|
|
|
|
|
* Fundado el 2020-11-02, tenemos grupo de telegram y BBB.
|
|
|
* [Cryptpad del grupo de domótica](https://cryptpad.fr/pad/#/2/pad/edit/+K6cC9t-UGKfem6AdmkJ93ja/)
|
|
|
|
|
|
|
|
|
## Hardware para empezar
|
|
|
|
|
|
* __Wemos__: [este](https://es.aliexpress.com/item/32843602421.html)
|
|
|
es el micro procesador que vamos a usar para el sensor. Se puede
|
|
|
programar con el IDE Arduino. Este es el ESP8285, equivale a un
|
|
|
ESP8266 con 1Mb de flash.
|
|
|
* __Sensor de temperatura/humedad__
|
|
|
* __RTC y tarjeta SD__ Como [este](https://es.aliexpress.com/item/32826265932.html)
|
|
|
* __Pantalla OLED__ Como
|
|
|
[esta](https://es.aliexpress.com/item/1005001636650130.html)
|
|
|
compatible con la mecánica Wemos
|
|
|
* __Módulo de gestión de batería__ Como
|
|
|
[este](https://es.aliexpress.com/item/32796003002.html).Para
|
|
|
alimentar el sensor con una batería de 3,3 volt
|
|
|
|
|
|
Ver la tabla de componentes
|
|
|
[aquí](https://cryptpad.fr/sheet/#/2/sheet/edit/PYqEabbLSfwUlQticILskoOC/)
|
|
|
|
|
|
## MQTT
|
|
|
|
|
|
_**M**essage **Q**ueuing **T**elemetry **T**ransport_, es un protocolo
|
|
|
**ligero** (bajo consumo de memoria y cpu) diseñado especificamente
|
|
|
para que dispositivos de bajo consumo transmitan datos de banda
|
|
|
estrecha (con velocidades muy bajas). El protocolo funciona sobre
|
|
|
TCP/IP (otro protocolo, "el de internet"). Es un protocolo viejecito
|
|
|
(1999), lo que pasa es que se ha puesto de moda por que encaja muy
|
|
|
bien con todo el tema de IoT (_**I**nternet **o**f **T**hings_)
|
|
|
|
|
|
### Conceptos
|
|
|
|
|
|
_Broker_
|
|
|
|
|
|
: Es un _middleware_ (un intermediario) entre los _publishers_
|
|
|
(agentes que envían datos) y _receivers_ (agentes que reciben los
|
|
|
datos)
|
|
|
|
|
|
_Publisher_
|
|
|
|
|
|
: Un agente que envía datos al _Broker_, puede ser un dispositivo
|
|
|
sensor, un demonio monitorizando un servidor, una raspi, etc. etc.
|
|
|
|
|
|
_Subscriber_
|
|
|
|
|
|
: Es el receptor de los datos enviados por el _Publisher_
|
|
|
|
|
|
_Topic_
|
|
|
|
|
|
: Los _Publisher_ y _Subscriber_ no se relacionan directamente. Cuando
|
|
|
un _publisher_ envía datos al _broker_ los asocia a un _topic_. El
|
|
|
_topic_ es una cadena en forma de jerarquia (p.ej.
|
|
|
/sensor/cocina/temperatura), el carácter '/' actúa como separador de
|
|
|
nivel, cada campo separado por '/' representa un nivel. Los puedes
|
|
|
organizar como quieras. Cuando un _subscriber_ se conecta al
|
|
|
_broker_ especifica los _topic_ en los que está interesado. El
|
|
|
_broker_ le hará llegar todos los mensajes de esos _topic_.
|
|
|
|
|
|
Tenemos dos operadores o máscaras para especificar las
|
|
|
subscripciones: `#` y `+`.
|
|
|
|
|
|
Supongamos que tenemos los siguientes _topic_:
|
|
|
|
|
|
* `/sensor/cocina/temperatura`
|
|
|
* `/sensor/cocina/humedad`
|
|
|
* `/sensor/cocina/humo`
|
|
|
* `/sensor/salon/temperatura`
|
|
|
* `/sensor/salon/humedad`
|
|
|
* `/sensor/salon/humo`
|
|
|
|
|
|
Con la especificación `/sensor/+/temperatura` me suscribo a todos
|
|
|
los sensores de temperatura. `+` encaja con un nivel simple.
|
|
|
|
|
|
Con la especificación `/sensor/#` me suscribo a todos los sensores.
|
|
|
`#` encaja con múltiples niveles.
|
|
|
|
|
|
Si organizamos los niveles de los _topic_ con lógica, podremos
|
|
|
gestionar fácilmente las suscripciones.
|
|
|
|
|
|
_message_
|
|
|
|
|
|
: Los datos que son enviados y recibidos
|
|
|
|
|
|
### Versiones del protocolo
|
|
|
|
|
|
* V3.1.1
|
|
|
* V5.0
|
|
|
|
|
|
### Brokers MQTT
|
|
|
|
|
|
Hay muchos brokers, esta lista es muy parcial pero todos los que están
|
|
|
tienen licencia libre.
|
|
|
|
|
|
* __Mosquitto__: Mosquitto es un broker sencillo y que aparece en un
|
|
|
montón de tutoriales disponibles en internet. Está incluido en los
|
|
|
repos de Debian y Ubuntu (seguramente no muy actualizado) y hay ppa
|
|
|
disponible. La principal pega de Mosquitto es que no soporta
|
|
|
"clustering" (varios brokers funcionando en paralelo) que es la
|
|
|
forma natural de escalar la carga en el servido y dar redundancia.
|
|
|
Es práctico para desarrollar aplicaciones pero puede dar problemas
|
|
|
si lo quieres usar en un entorno de producción.
|
|
|
* __RabittMQ__: Es un broker multiprotocolo así que no solo soporta
|
|
|
MQTT. El soporte para distintos protocolos de colas de mensajes se
|
|
|
implementa mediante plugins. Soporta clustering así que es escalable
|
|
|
para aguantar cargas grandes de peticiones y se puede implementar
|
|
|
redundancia. El soporte de MQTT no es completo, no tiene soporte
|
|
|
para MQTT V5.0 ni para todas las carácteristicas de MQTT V3.1.1 (por
|
|
|
ejemplo no soporta QoS2)
|
|
|
* __VerneMQ__: Es un broker MQTT puro (no es multiprotocolo) Soporta
|
|
|
clustering y todas las versiones de MQTT, aparentemente con todas
|
|
|
sus funcionalidades.
|
|
|
|
|
|
### Pruebas con _Mosquitto_
|
|
|
|
|
|
Vamos a hacer pruebas con el _broker_ más sencillo: _Mosquitto_
|
|
|
|
|
|
En Ubuntu y derivadas es muy fácil de instalar, añadimos el origen de
|
|
|
paquetes oficiales para estar a la última, instalamos el paquete
|
|
|
`mosquitto` y el paquete `mosquitto-clients`, los clientes nos vendrán
|
|
|
bien para hacer pruebas. En otras distribuciones tendrás que mirar
|
|
|
como se instala, pero no puede ser muy complicado.
|
|
|
|
|
|
```bash
|
|
|
sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
|
|
|
sudo apt-get update
|
|
|
sudo apt install mosquitto mosquitto-clients
|
|
|
```
|
|
|
|
|
|
En Ubuntu y derivadas **queda lanzado el servicio** y podemos hacer
|
|
|
pruebas con los clientes instalados. Si después queremos instalar el
|
|
|
_Mosquitto_ de otra manera (con _docker_ por ejemplo) hay que
|
|
|
acordarse de parar el servicio.
|
|
|
|
|
|
#### Probando
|
|
|
|
|
|
En un terminal con el comando `mosquitto_sub -h localhost -t test`
|
|
|
lanzamos un _subscriber_ que atiende al _topic_ test.
|
|
|
|
|
|
Desde otro terminal con el comando `mosquitto_pub -h localhost -t test
|
|
|
-m "Hola Mundo"` ejecutamos un _publisher_ que manda el mensaje "Hola
|
|
|
Mundo" al _topic_ test.
|
|
|
|
|
|
En la primera ventana podemos ver:
|
|
|
|
|
|
```bash
|
|
|
$ mosquitto_sub -h localhost -t test
|
|
|
Hola mundo
|
|
|
```
|
|
|
|
|
|
Se ha recibido el mensaje en el _topic_ suscrito.
|
|
|
|
|
|
#### Probando con python
|
|
|
|
|
|
Vamos a ver como usar el _mqtt_ desde Python. Así queda mucho más
|
|
|
claro como funciona el _broker_
|
|
|
|
|
|
|
|
|
Creamos un entorno virtual y lo activamos (yo lo he llamado `paho`),
|
|
|
en ese entorno instalamos la librería: `pip install paho-mqtt`
|
|
|
|
|
|
Creamos un programa _subscriber_:
|
|
|
|
|
|
```python
|
|
|
import paho.mqtt.client as mqtt
|
|
|
import time
|
|
|
|
|
|
|
|
|
# la rutina a ejecutar cuando recibimos un mensaje
|
|
|
def on_message(client, userdata, message):
|
|
|
print("received message: ", str(message.payload.decode("utf-8")))
|
|
|
|
|
|
|
|
|
# la rutina a ejecutar al recibir CONNACK
|
|
|
def on_connect(client, b, c, rt):
|
|
|
print("Connected with result " + str(rt))
|
|
|
|
|
|
# hacemos la suscripcion dentro de la rutina on_connect
|
|
|
# de esta forma si tenemos reconexiones ya nos aseguramos
|
|
|
# la suscripcion
|
|
|
client.subscribe("ALEATORIOS")
|
|
|
|
|
|
|
|
|
# dirección del broker
|
|
|
mqttBroker = "localhost"
|
|
|
|
|
|
# creamos un "cliente"
|
|
|
client = mqtt.Client("subs-1")
|
|
|
client.on_connect = on_connect
|
|
|
client.on_message = on_message
|
|
|
|
|
|
# conexión al broker
|
|
|
client.connect(mqttBroker)
|
|
|
|
|
|
# lanzamos un loop no bloqueante
|
|
|
client.loop_start()
|
|
|
|
|
|
# Escuchamos durante 30 segundos y paramos el programa.
|
|
|
time.sleep(30)
|
|
|
client.loop_stop()
|
|
|
```
|
|
|
|
|
|
|
|
|
Y este sería el programa _publisher_
|
|
|
|
|
|
```python
|
|
|
import paho.mqtt.client as mqtt
|
|
|
from random import randrange, uniform
|
|
|
import time
|
|
|
|
|
|
|
|
|
# definimos la rutina a ejecutar cuando recibimos CONNACK
|
|
|
def on_connect(client, userdata, flags, rc):
|
|
|
print("Connected with result " + str(rc))
|
|
|
|
|
|
|
|
|
# definimos la dirección del broker
|
|
|
mqttBroker = "localhost"
|
|
|
|
|
|
# creamos un "cliente"
|
|
|
client = mqtt.Client("publisher-1")
|
|
|
client.on_connect = on_connect
|
|
|
|
|
|
# conexión al broker
|
|
|
client.connect(mqttBroker)
|
|
|
|
|
|
# Bucle infinito, publicamos un número aleatorio y esperamos 1 sg
|
|
|
while True:
|
|
|
randNumber = uniform(0, 10)
|
|
|
client.publish("ALEATORIOS", randNumber)
|
|
|
print("Publicado " + str(randNumber) + " en el topic ALEATORIOS")
|
|
|
time.sleep(1)
|
|
|
```
|
|
|
|
|
|
Podemos ver los programas en acción ejecutando cada uno en su terminal
|
|
|
(terminal=ventana de comandos) ¡Recuerda activar el entorno virtual
|
|
|
en todos los terminales que abras!
|
|
|
|
|
|
##### ¿Qué está pasando aquí?
|
|
|
|
|
|
Cada vez que desde un cliente le pedimos algo al _broker_ este nos
|
|
|
responde con una señal, pero ¡ojo! el protocolo es asíncrono, así que
|
|
|
mas que una conversación entre cliente y servidor tenemos un
|
|
|
intercambio de correos.
|
|
|
|
|
|
Por ejemplo, cuando nosotros le mandamos la petición de conexión al
|
|
|
_broker_ debería llegarnos un _CONNACK_ desde el mismo. En el
|
|
|
_CONNACK_ el _broker_ nos adjunta tres campos: _user data_, _flags_ y
|
|
|
_result code_. El campo más interesante probablemente sea el _result
|
|
|
code_, estos son los valores definidos en el protocolo:
|
|
|
|
|
|
| rc | Significado |
|
|
|
| :-----: |-------------------------------------------------|
|
|
|
| 0 | Connection successful |
|
|
|
| 1 | Connection refused – incorrect protocol version |
|
|
|
| 2 | Connection refused – invalid client identifier |
|
|
|
| 3 | Connection refused – server unavailable |
|
|
|
| 4 | Connection refused – bad username or password |
|
|
|
| 5 | Connection refused – not authorised |
|
|
|
| 6-255 | Currently unused. |
|
|
|
|
|
|
La biblioteca _paho-mqtt_ nos permite definir rutinas ___callback__
|
|
|
que la librería invocará cuando se produzcan ciertos eventos.
|
|
|
|
|
|
Un par de ejemplos: un evento de conexión reconocida (se ha recibido
|
|
|
el _CONNACK_) hará que se ejecute el _callback on_connect_, el evento
|
|
|
"recibir un mensaje" hará que _paho_ intente ejecutar el _callback
|
|
|
on_message_. Esta tabla cubre los principales eventos:
|
|
|
|
|
|
| Evento | _Callback_ |
|
|
|
|---------------------------|------------------|
|
|
|
| Conexión reconocida | `on_connect` |
|
|
|
| Desconexión reconocida | `on_disconnect` |
|
|
|
| Suscripción reconocida | `on_subscribe` |
|
|
|
| De-suscripción reconocida | `on_unsubscribe` |
|
|
|
| Publicación reconocida | `on_publish` |
|
|
|
| Mensaje recibido | `on_message` |
|
|
|
| Info de log disponible | `on_log` |
|
|
|
|
|
|
Los ejemplos que puse son muy sencillos, si queremos escribir un
|
|
|
código más robusto hay que tener en cuenta todo lo que el protocolo
|
|
|
ofrece y que es un protocolo asíncrono. Un par de ejemplos de mejoras
|
|
|
|
|
|
* La función `on_connect` debería comprobar el _result code_ y no
|
|
|
dejar continuar el programa sin tener una conexión verificada.
|
|
|
* La función `on_message` seguramente tendrá que procesar el _topic_
|
|
|
del mensaje y puede que también la _qos_
|
|
|
|
|
|
|
|
|
## influxdb
|
|
|
|
|
|
* <https://discourse.nodered.org/t/mqtt-node-red-influxdb/34706>
|
|
|
* <https://diyi0t.com/visualize-mqtt-data-with-influxdb-and-grafana/>
|
|
|
* <https://dev.to/project42/install-grafana-influxdb-telegraf-using-docker-compose-56e9>
|
|
|
* <https://lazyadmin.nl/it/installing-grafana-influxdb-and-telegraf-using-docker/>
|
|
|
|
|
|
|
|
|
_Influxdb_ es una base de datos especializada en series temporales de
|
|
|
datos. Eso hace que sea mucho más eficiente que una base de datos
|
|
|
relacional tratando este tipo de datos. Aunque internamente cambia
|
|
|
bastante el funcionamiento el lenguaje de consultas no es muy
|
|
|
diferente de SQL. Otra ventaja relacionada con nuestro escenario es que
|
|
|
se integra muy bien con _Grafana_.
|
|
|
|
|
|
Hasta ahora _influxdb_ viene con varias aplicaciones asociadas:
|
|
|
|
|
|
_Telegraf_
|
|
|
|
|
|
: un agente de recolección de datos, para capturar datos de _stacks_ y
|
|
|
otros sistemas
|
|
|
|
|
|
_Cronograf_
|
|
|
|
|
|
: Un visualizador de datos al estilo de _Graphana_
|
|
|
|
|
|
Kapacitor
|
|
|
|
|
|
: un motor de procesado de datos en tiempo real especializado en
|
|
|
series temporales
|
|
|
|
|
|
Pero está disponible la versión __InfluxDB OSS 2.0__ que integra todas
|
|
|
las herramientas en un único programa. Por lo que veo la instalación
|
|
|
es por binarios únicamente y además __no es compatible con
|
|
|
Raspberry__. Parece interesante pero por ahora lo dejamos.
|
|
|
|
|
|
Si instalamos el _Influxdb_ clásico nos quedamos con la versión 1.8.3
|
|
|
(en este momento). Una vez instalada y arrancado el servicio lo
|
|
|
podemos probar preguntando por las bases de datos disponibles (solo
|
|
|
está la _internal_)
|
|
|
|
|
|
```bash
|
|
|
$ influx
|
|
|
Connected to http://localhost:8086 version 1.8.3
|
|
|
InfluxDB shell version: 1.8.3
|
|
|
> show databases
|
|
|
name: databases
|
|
|
name
|
|
|
----
|
|
|
_internal
|
|
|
>
|
|
|
```
|
|
|
|
|
|
Que no os despiste el interfaz http, no es _human friendly_ ni
|
|
|
funciona con navegadores (en esta versión de _influxdb_). Si que
|
|
|
podemos interrogarlo con _curl_ por ejemplo y nos responderá en
|
|
|
perfecto _json_:
|
|
|
|
|
|
```bash
|
|
|
$ curl -G http://localhost:8086/query --data-urlencode "q=SHOW DATABASES"
|
|
|
|
|
|
{"results":[{"statement_id":0,"series":[{"name":"databases","columns":["name"],"values":[["_internal"]]}]}]}
|
|
|
```
|
|
|
|
|
|
Por lo demás trabajar con _InfluxDB_ no es tan diferente de trabajar
|
|
|
con una base de datos relacional de toda la vida.
|
|
|
|
|
|
* _InfluxDB_ está optimizada para trabajar con series de datos
|
|
|
temporales, es más rápida (con este tipo de datos) que las bases de
|
|
|
datos relacionales clásicas
|
|
|
* Cambia un poco la terminología:
|
|
|
* La base de datos clásica era una colección de tablas, la de
|
|
|
_Influx_ puede verse como una colección de "medidas" (_measurements_)
|
|
|
* Las "medidas" se parecen a las tablas de las bases de datos
|
|
|
relacionales, pero:
|
|
|
* Siempre tienen que tener una referencia temporal
|
|
|
(_timestamp_, basicamente nanosegundos desde el _Linux Epoch_)
|
|
|
* Se distingue entre campos (_fields_) y etiquetas (_tags_),
|
|
|
equivalen a los campos (columnas) de las tablas de las bases
|
|
|
de datos relacionales, pero: **las etiquetas están
|
|
|
indexadas** y los campos no.
|
|
|
* los registros, las filas de las tablas, se llaman puntos
|
|
|
* Se pueden ajustar las políticas de retención de datos, es decir,
|
|
|
cuanto tiempo se mantienen en la base de datos. Depende de para que
|
|
|
quieras usar los datos, a lo mejor quieres un histórico de una hora
|
|
|
o de cinco años. Ajustar bien las políticas de retención influye en
|
|
|
el rendimiento de la base de datos.
|
|
|
|
|
|
### Instalación de _InfluxDB_
|
|
|
|
|
|
Dependerá del sistema operativo, por ejemplo para Linux Mint:
|
|
|
|
|
|
```bash
|
|
|
wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add -
|
|
|
#source /etc/lsb-release
|
|
|
DISTRIB_ID=ubuntu
|
|
|
DISTRIB_CODENAME=focal
|
|
|
echo "deb https://repos.influxdata.com/${DISTRIB_ID} ${DISTRIB_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
|
|
|
|
|
|
apt update
|
|
|
apt install influxdb
|
|
|
apt install telegraf
|
|
|
```
|
|
|
|
|
|
Una vez instalado verifica que el servicio está arrancado.
|
|
|
|
|
|
El cliente de la base de datos se llama _influx_ si ejecutamos el
|
|
|
cliente podemos preguntar por las bases de datos presentes con: `show
|
|
|
databases` (solo muestra la base de datos interna)
|
|
|
|
|
|
Una sesión completa
|
|
|
* Creamos la base de datos
|
|
|
* La ponemos como base de datos activa
|
|
|
* Insertamos datos
|
|
|
|
|
|
```bash
|
|
|
influx -precision rfc3339
|
|
|
Connected to http://localhost:8086 version 1.8.3
|
|
|
InfluxDB shell version: 1.8.3
|
|
|
> show databases
|
|
|
name: databases
|
|
|
name
|
|
|
----
|
|
|
_internal
|
|
|
|
|
|
>create database mydb
|
|
|
> show databases
|
|
|
name: databases
|
|
|
name
|
|
|
----
|
|
|
_internal
|
|
|
mydb
|
|
|
|
|
|
> use mydb
|
|
|
Using database mydb
|
|
|
|
|
|
> insert temperature,location=campo external=13,internal=23
|
|
|
> insert temperature,location=ciudad external=19, internal=22
|
|
|
```
|
|
|
|
|
|
Las lineas de los _insert_ siguen el esquema:
|
|
|
|
|
|
`<measurement>[,<tag-key>=<tag-value>...] <field-key>=<field-value>[,<field2-key>=<field2-value>...] [unix-nano-timestamp]`
|
|
|
|
|
|
El primer grupo son los _tags_ que **están indexados**. En nuestro
|
|
|
ejemplo el _tag_ sería `location`. El segundo grupo son los _fields_
|
|
|
(no indexados), en nuestro ejemplo tendríamos dos `external` e
|
|
|
`internal`. Opcionalmente podemos escribir el _timestamp_ o dejar que
|
|
|
_influx_ lo ponga automáticamente (pondrá el instante en que se
|
|
|
realiza la inserción)
|
|
|
|
|
|
### Un ejemplo con python
|
|
|
|
|
|
Lo primero es instalar la biblioteca de python así que en nuestro
|
|
|
entorno virtual ejecutamos `pip install influxdb`
|
|
|
|
|
|
Un programa python chorras para ejecutar las inserciones del ejemplo anterior:
|
|
|
|
|
|
```python
|
|
|
from influxdb import InfluxDBClient
|
|
|
|
|
|
client = InfluxDBClient(host=localhost, port=8086)
|
|
|
client.switch_database('mydb')
|
|
|
client.write_points("temperature,location='countryside' external=13,internal=23", protocol='line')
|
|
|
client.write_points("temperature,location='city' external=19,internal=22", protocol='line')
|
|
|
```
|
|
|
|
|
|
Si después de ejecutar el programa vamos al cliente _influx_:
|
|
|
|
|
|
```bash
|
|
|
> use mydb
|
|
|
Using database mydb
|
|
|
> show measurements
|
|
|
name
|
|
|
----
|
|
|
temperature
|
|
|
> select * from temperature
|
|
|
name: temperature
|
|
|
time external internal location
|
|
|
---- -------- -------- --------
|
|
|
2020-11-27T15:23:20.523830387Z 13 23 countryside
|
|
|
2020-11-27T15:23:33.459690565Z 19 22 city
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Análisis y Visualización de datos
|
|
|
|
|
|
* __Metabase__: Visualización de gráficos sencilla y potente.
|
|
|
* __Grafana__: Plataforma de visualización y análisis de datos muy completa.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## node-red
|
|
|
|
|
|
|
|
|
### Instalación en Linux
|
|
|
|
|
|
Para instalar node-red en linux necesitamos instalar primero
|
|
|
`node.js`. Hay varias formas de instalar `node.js`, yo voy a optar por
|
|
|
instalar `nvm` que es el **n**ode **v**ersion **m**anager.
|
|
|
|
|
|
Para ello ejecutamos el siguiente comando (la versión actual de `nvm`
|
|
|
es la 0.37.0)
|
|
|
|
|
|
```bash
|
|
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.0/install.sh | bash
|
|
|
```
|
|
|
|
|
|
El script de instalación añade las siguientes lineas al fichero
|
|
|
`~/.bashrc`, nosotros las eliminamos de `~/.bashrc` y las movemos al
|
|
|
fichero `~/.profile`
|
|
|
|
|
|
```bash
|
|
|
export NVM_DIR="$HOME/.nvm"
|
|
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
|
|
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
|
|
```
|
|
|
|
|
|
Para comprobar la instalación usamos `command -v nvm` que nos
|
|
|
devolverá `nvm`. `which` no funciona en este caso por que es un script
|
|
|
pensado para invocarlo con `source`
|
|
|
|
|
|
### Instalación de `node.js`
|
|
|
|
|
|
Ahora que tenemos `nvm` instalado, ya podemos instalar fácilmente la versión o versiones que queramos de `node.js`
|
|
|
|
|
|
```bash
|
|
|
nvm ls-remote # para listar las versiones disponibles
|
|
|
nvm install node # instala la última versión disponible
|
|
|
nvm install --lts # instala la versión LTS
|
|
|
```
|
|
|
|
|
|
### Instalación de `node-red`
|
|
|
|
|
|
Una vez instalado el `node.js` instalar el `node-red` es muy fácil:
|
|
|
activar el `node.js` que hemos instalado y hacer la instalación de
|
|
|
`node-red`
|
|
|
|
|
|
```bash
|
|
|
nvm use node
|
|
|
npm install -g --unsafe-perm node-red
|
|
|
```
|
|
|
|
|
|
|
|
|
## Instalación del IDE Arduino en Linux para trabajar con Wemos D1
|
|
|
|
|
|
Descargamos el IDE de la [pagina
|
|
|
web](https://www.arduino.cc/en/software). Para proceder a la
|
|
|
instalación se puede consultar [la guía de postinstalación de Linux
|
|
|
Mint](https://gitlab.com/salvari/linuxmint_ulyana_20) que detalla
|
|
|
todos los pasos.
|
|
|
|
|
|
Solo necesitamos habilitar el soporte para ESP8266, añadiendo la linea
|
|
|
siguiente a nuestras preferencias de Arduino:
|
|
|
|
|
|
`http://arduino.esp8266.com/stable/package_esp8266com_index.json`
|
|
|
|
|
|
|
|
|
|
|
|
## Configuración de mini-PC como servidor
|
|
|
|
|
|
Describimos la instalación en un mini-pc Beelink T34 (con 8 gb de RAM
|
|
|
y 256Gb de disco duro SSD). No es obligatorio hacerlo como
|
|
|
describimos, esto es solo para referencia.
|
|
|
|
|
|
Nos hemos decidido por instalar Debian en el mini-pc. Hay varias
|
|
|
formas de instalar Debian, pero como nosotros queremos un Debian sin
|
|
|
interfaz gráfico y con lo mínimo, creemos que lo más fácil es usar el
|
|
|
`netinst`.
|
|
|
|
|
|
Descargamos la imagen iso de `netinst` desde [la página de
|
|
|
Debian](https://cdimage.debian.org/debian-cd/current/amd64/bt-cd/) (la
|
|
|
hemos descargado via torrent)
|
|
|
|
|
|
Desde linux hemos usado Etcher (es multiplataforma) para grabar la
|
|
|
image iso descargada en una memoria USB.
|
|
|
|
|
|
Conectamos nuestro mini-PC a un teclado usb y a un monitor (hemos
|
|
|
usado un coversor HDMI-VGA) y conectamos la memoria USB en algúno de
|
|
|
los puertos libres, también le hemos dado internet con un cable
|
|
|
ethernet a nuestro router.
|
|
|
|
|
|
Al arrancar el mini-PC veremos un aviso: pulsando F7 nos deja elegir
|
|
|
el dispositivo de arranque. Elegimos arrancar desde la memoria USB e
|
|
|
iniciamos la instalación de Debian, con particionado manual y sin LVM.
|
|
|
|
|
|
Hemos creado tres particiones:
|
|
|
|
|
|
| Particion | Tamaño | Tipo | Punto de montaje | Comentarios |
|
|
|
|-----------|--------|------|--------------------|-----------------------------------------------------------|
|
|
|
| /dev/sda1 | 511Mb | EFI | /boot/efi | La crea el programa de instalación |
|
|
|
| /dev/sda2 | 55Gb | ext4 | / | root |
|
|
|
| /dev/sda4 | 171Gb | ext4 | /store | Dejamos casi todo el espacio disponible en esta partición |
|
|
|
|
|
|
|
|
|
El programa de instalación nos ha pedido drivers adicionales pero lo
|
|
|
hemos ignorado.
|
|
|
|
|
|
Hemos escogido idioma inglés con teclado español. También hemos
|
|
|
escogido locales `es_ES-UTF-8`
|
|
|
|
|
|
**Solo** hemos instalado el openssh server y las herramientas básicas.
|
|
|
Tendremos que instalar muchas más cosas pero eso nos deja un sistema
|
|
|
lo más limpio posible.
|
|
|
|
|
|
Tras completar la instalación el sistema **no** arranca normalmente se
|
|
|
queda pillado en el _prompt_ de _grub_. Tras teclear `exit` en el
|
|
|
prompt arranca normalmente.
|
|
|
|
|
|
Se soluciona ejecutando como _root_ `grub-install` y ya no vuelve a fallar.
|
|
|
|
|
|
Una vez arrancado el sistema podemos conectarnos via ssh.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Referencias
|
|
|
|
|
|
### Wiki de Bricolabs
|
|
|
|
|
|
* [Raspberry Pi, configuración para IOT](https://bricolabs.cc/wiki/guias/raspberry_iot)
|
|
|
* [Sistema IOT de Bricolabs](https://bricolabs.cc/wiki/proyectos/sistema_iot_bricolabs)
|
|
|
|
|
|
### Referencias MQTT
|
|
|
|
|
|
* [Buenos apuntes para aprender de MQTT](https://www.hivemq.com/mqtt-essentials/)
|
|
|
* [Para empezar con python y MQTT (muy completo)](http://www.steves-internet-guide.com/into-mqtt-python-client/)
|
|
|
* [Enviar datos desde ESP via mqtt](https://diyi0t.com/microcontroller-to-raspberry-pi-wifi-mqtt-communication/)
|
|
|
* [Visualizar datos (cont. del ant.)](https://diyi0t.com/visualize-mqtt-data-with-influxdb-and-grafana/)
|
|
|
|
|
|
### Referencias _Influxdb_
|
|
|
|
|
|
* [Getting started](https://docs.influxdata.com/influxdb/v1.7/introduction/getting-started/)
|
|
|
* [Getting started with Influxdb OSS 2.0](https://docs.influxdata.com/influxdb/v2.0/get-started/)
|
|
|
* [Guia de Influxdb](https://devconnected.com/the-definitive-guide-to-influxdb-in-2019/)
|
|
|
* [Instrucciones de instalación para la versión clásica y la nueva 2.0 en ubuntu y debian](https://devconnected.com/how-to-install-influxdb-on-ubuntu-debian-in-2019/#Option_2_Adding_the_repositories_to_your_package_manager)
|
|
|
* [otro getting started](https://www.influxdata.com/blog/getting-started-with-influxdb-2-0-scraping-metrics-running-telegraf-querying-data-and-writing-data/)
|
|
|
* [Python e Influxdb OSS 2.0](https://www.influxdata.com/blog/getting-started-with-python-and-influxdb-v2-0/)
|
|
|
* [Docker compose: Grafana/Influx/Telegraf](https://dev.to/project42/install-grafana-influxdb-telegraf-using-docker-compose-56e9)
|
|
|
* [idem](https://lazyadmin.nl/it/installing-grafana-influxdb-and-telegraf-using-docker/)
|
|
|
* [idem, tiene dos partes](https://thenewstack.io/how-to-setup-influxdb-telegraf-and-grafana-on-docker-part-1/)
|
|
|
* [Acumulados y caducidad: _Continous query and retention policy_](https://docs.influxdata.com/influxdb/v1.8/guides/downsample_and_retain/)
|
|
|
|
|
|
### Home assistant seguros
|
|
|
|
|
|
* <https://makezine.com/2020/03/17/private-by-design-free-and-private-voice-assistants/>
|
|
|
* <https://makezine.com/2020/08/03/set-up-your-own-private-smart-home/>
|
|
|
* https://makezine.com/projects/mycroft-the-open-source-private-voice-assistant-on-raspberry-pi/>
|
|
|
* Magpi vol 99, pag 54 <http://magpi.cc>
|
|
|
|
|
|
### Ejemplos del escenario básico que queremos implementar
|
|
|
|
|
|
* [Visualizar datos con mqtt-influxdb-grafana (bridge-python)](https://diyi0t.com/visualize-mqtt-data-with-influxdb-and-grafana/)
|
|
|
* [Una configuración con Telegraf](https://screenzone.eu/arduino-mqtt-sensor-grafana/)
|
|
|
* [nilhcem (web)](http://nilhcem.com/iot/home-monitoring-with-mqtt-influxdb-grafana)
|
|
|
|
|
|
### Para revisar
|
|
|
|
|
|
* [Pagina especializada en IoT](https://diyi0t.com/)
|
|
|
* <https://esphome.io/index.html#guides>
|