Conectar monitor de consumo eléctrico con emoncms.org (II)

Estándar

En la última entrada, habíamos visto cómo conectar el medidor de consumo OWL-CM160 a un PC, para descargar el consumo. También habíamos visto que EmonCMS era una web muy chula a la que subir nuestros consumos, pero que no tenía una opción para subir directamente un fichero CSV. Además, esto de tener que subir manualmente ficheros CSV cada cierto tiempo no nos gustaba demasiado, y la idea era montar algo para tener siempre el consumo disponible en tiempo real.

La opción que parece mejor, de lejos, es tener la estación base del medidor de consumo conectada a algún ordenador que tengamos conectado las 24h, y trabajar desde ahí. Pero muchas veces eso no es posible, ya sea porque no tenemos ningún ordenador así, o bien porque la ubicación no nos vaya bien. En mi caso, era esto último, ya que si ponía la estación base enchufada a mi mini-servidor la señal de la pinza amperimétrica no llegaba bien (el contador queda lejos). Por tanto, y aprovechando que tenía una Raspberry Pi tirada por ahí, decidí aprovecharla para la tarea. Le puse una tarjetilla SD adecuada y un adaptador Wifi, le instalé una Raspbian, y alimentándola con cualquier cargador de móvil un poco bueno (que dé 1-1,5 A por lo menos, aunque yo me compré el oficial), pues ya tengo un ordenador listo para colocarlo en cualquier parte. A partir de aquí, todo lo que cuento funciona exactamente igual para la Raspberry Pi que para cualquier ordenador con Linux, ya que Raspbian no deja de ser una distribución Linux como otra cualquiera.

A continuación explico más o menos lo que hice, paso a paso.

Instalar eagle-owl

Esto no tiene mucho misterio. Lo primero es bajarse la última versión desde el repositorio Git, por ejemplo creando el directorio ~/git, y bajándolo allí:

mkdir ~/git
cd ~/git
git clone https://github.com/cornetp/eagle-owl.git

Una vez está aquí, hay que compilarlo. Para ello hay que instalar previamente un par de paquetes (con el compilador y demás), que suelen estar agrupados en el paquete virtual build-essential:

cd eagle-owl
sudo apt-get install build-essential
cd src
make

Tardará un ratito (especialmente si es una raspberry), y al acabar ya tendremos los ejecutables compilados (cm160 y db_import). Siempre siguiendo el manual, ahora hay que copiar estos ficheros a algún sitio (yo los puse en /opt/eagleowl), y luego copiar el fichero eagleowl.conf a /etc, editándolo para poner la ruta que hemos creado en  install_path:

mkdir /opt/eagleowl
cp cm160 db_import /opt/eagleowl
sudo cp eagleowl.conf /etc
Así debe quedar el fichero de configuración de eagle-owl

Así debe quedar el fichero de configuración de eagle-owl

Otra cosa que hay que configurar es que eagle-owl se arranque automáticamente cada vez que arranca el ordenador. El problema es que el script de arranque que viene en el repositorio es para upstart (Ubuntus y derivados), por lo que, entre que mi Raspbian está basada en Debian y que quiero hacerlo un pelín diferente, me he hecho mi propio script, que hay que copiar en /etc/init.d:

#!/bin/bash                                                                                                                                                                                                                                  
### BEGIN INIT INFO                                                                                                                                                                                                                          
# Provides:          eagleowl                                                                                                                                                                                                                
# Required-Start:    $remote_fs $syslog $time                                                                                                                                                                                                
# Required-Stop:     $remote_fs $syslog                                                                                                                                                                                                      
# Default-Start:     2 3 4 5                                                                                                                                                                                                                 
# Default-Stop:      0 1 6                                                                                                                                                                                                                   
# Short-Description: Programa para descargar logs de OWL-CM160
# Description:       Ejecuta eagle-owl dentro de una sesión screen
### END INIT INFO

# /etc/init.d/eagleowl

if [ -f /lib/lsb/init-functions ]; then
        . /lib/lsb/init-functions
fi

source /etc/eagleowl.conf

# Carry out specific functions when asked to by the system
case "$1" in
        start)
                echo "Starting eagleowl "
                start-stop-daemon --start -x $install_path/cm160 --chuid pi --chdir $install_path --exec /usr/bin/screen -- -d -m $install_path/cm160
                ;;
        stop)
                echo "Stopping eagleowl"
                start-stop-daemon --stop -R5 --name cm160
                ;;
        restart|reload)
                $0 stop
                $0 start
                ;;
        status)
#               status_of_proc cm160
                pid=$(pgrep cm160 | head -n1)
                if [ $pid ]; then
                        echo "eagleowl funcionando con PID $pid"
                else
                        echo "eagleowl no está activo"
                fi
                ;;
        *)
                echo "Usage: /etc/init.d/eagleowl {start|stop|restart|status}"
                exit 1
                ;;
esac

exit 0

Lo que he modificado respecto a un script de arranque «estándar» son un par de cositas:

  • Al principio leo el fichero de configuración de eagleowl (/etc/eagleowl.conf), de manera que tengo acceso a la ruta en la que está instalado ($install_path).
  • He indicado que el comando se ejecute con el usuario pi (que es el por defecto en la raspberry)
  • No arranco el comando cm160 tal cual, sino que lo hago dentro de una sesión screen. Para el que no lo conozca, screen es una especie de consola «virtual» que se ejecuta en segundo plano. La he usado para ejecutar eagleowl porque no he encontrado manera de redirigir la salida de texto del comando cm160 sin que dé problemas. De esta manera, se ejecuta en su propia sesión, y todo va bien.

Una vez el script está copiado a /etc/init.d con el nombre «eagleowl», le indicamos al sistema operativo que lo ejecute en cada arranque:

update-rc.d eagleowl defaults

Y ya lo tenemos todo configurado. De todas formas, antes de hacer este último paso conviene asegurarse de que eagleowl funciona correctamente. Para ello, ejecutamos tal cual el comando cm160, y si todo va bien veremos cómo, en primer lugar, se descarga el consumo que tenga acumulado el aparato, y a partir de ahí va mostrando por pantalla los consumos en tiempo real (una línea cada minuto, más o menos). Al mismo tiempo, los va guardando dentro del fichero /opt/eagleowl/eagleowl.db, que es el que realmente nos interesa.

Enviar consumos a EmonCMS

Ahora que ya tenemos a eagleowl funcionando, y guardando los consumos en tiempo real, es ahora de enviar el consumo a EmonCMS. Para ello, lo primero es extraer el consumo de la base de datos SQlite que usa eagleowl. Eso es tan fácil como ejecutar el siguiente comando:

sqlite3 -csv eagleowl.db "select year||'-'||substr('0'||month,-2,2)||'-'||substr('0'||day,-2,2)||' '||substr('0'||hour,-2,2)||':'||substr('0'||min,-2,2) date,cast(round(60*ch1_kw_avg) as int) w from energy_history where year=2015 and month=03 and day=16 order by date desc limit 1;"

Esto nos daría el último valor registrado en W para la fecha indicada (16 de marzo de 2015).

Y para enviar los datos a EmonCMS, basta con acceder a la URL:

http://emoncms.org/input/post.json?json={$key:$wattios}&apikey=$apikey

donde hay 3 valores a rellenar:

  • key: Es el identificador de lo que estamos midiendo, y es necesario porque EmonCMS soporta muchas entradas de datos diferentes (p. ejemplo, podríamos tener varios electrodomésticos monitorizados). Como yo estoy midiendo el consumo global, lo he llamado «kwgeneral».
  • wattios: Este es fácil, y es simplemente el consumo en wattios que hemos extraído antes de la base de datos de eagleowl
  • apikey: Esta es la clave de identificación para que EmonCMS nos reconozca. Se puede consultar en las opciones de EmonCMS, y hay dos, una de lectura y otra de escritura. Como en este caso estamos enviando datos para que se guarden, debe ser la de escritura.
Desde el apartado "Mi cuenta" de EmonCMS se pueden consultar las claves de API, tanto de lectura como de escritura

Desde el apartado «Mi cuenta» de EmonCMS se pueden consultar las claves de API, tanto de lectura como de escritura

Para enviar la información en tiempo real, lo suyo es crear una tarea cron que se ejecute cada minuto, y hacerlo todo allí. El siguiente script es el que uso yo:

#!/bin/bash

# Sube a emoncms el último valor de consumo
# Debería ejecutarse en un cron cada minuto

fichdb="/opt/eagleowl/eagleowl.db"
nodeid=0
apikey="efbda7b8s7f8c8e9a9f80f333aab2320"
key="kwgeneral"
diaactual=`date +%d`
mesactual=`date +%m`
anyoactual=`date +%Y`
medida=$(sqlite3 -csv $fichdb "select year||'-'||substr('0'||month,-2,2)||'-'||substr('0'||day,-2,2)||' '||substr('0'||hour,-2,2)||':'||substr('0'||min,-2,2) date,cast(round(60*ch1_kw_avg) as int) w from energy_history where year=$anyoactual and month=$mesactual and day=$diaactual order by date desc limit 1;")
wattios=$(echo $medida | cut -d, -f2)
url="http://emoncms.org/input/post.json?json={$key:$wattios}&apikey=$apikey"
if curl --retry 3 -s -S -o /dev/null "$url"; then
    logger -t EMON "Actualizado consumo en emoncms.org con valor $wattios W"
else
    logger -t EMON "Error actualizando consumo en emoncms.org ($wattios W)"
fi

Y con esto ya lo tenemos todo. Si vamos a EmonCMS, deberíamos ver ya en el apartado «Inputs» como tenemos una nueva entrada llamada kwgeneral, a la que van llegando datos periódicamente.

Aquí se ve la nueva entrada "kwgeneral", que se actualiza cada minuto. La otra entrada es otra que tengo para registrar la temperatura

Aquí se ve la nueva entrada «kwgeneral», que se actualiza cada minuto. La otra entrada es otra que tengo para registrar la temperatura

A partir de aquí habría que configurar EmonCMS, pero ese es otro tema bastante más amplio, y lo dejo para algún futuro artículo.

12 comentarios en “Conectar monitor de consumo eléctrico con emoncms.org (II)

  1. Gracias por esta aportación tan interesante, solo unos detalles:
    En en el programa de captura de datos eagle-owl (cm160.c), antes de compilar/instalar hay que «ajustar» el valor de la tensión, (como en mi caso a 220 V) , por defecto es de 230V (linea 87 de src/cm160.c), así las lecturas de potencia/energía serán reales y no un +5%.
    Por otra parte en la escritura al fichero .live, al mostrar la potencia, la linea de formato indica kW donde debería indicar W (linea 78 de src/cm160.c). No molesta para el uso normal de captura, pero si lo que se va a mostrar es precisamente esa linea, no es correcto.
    Gracias por todo.
    Ernesto.

    • Ojo, que aunque el voltaje «oficial» sea de 220V, en realidad se admite todo un margen de voltajes correctos, y puede ser perfectamente que el tuyo sea a 230 V ( o a 210 V). Lo suyo es mirarlo con un voltímetro, por si las moscas, y siempre teniendo en cuenta que tampoco hay garantía de que se mantenga constante. Igual hoy es a 230 V, y mañana fluctúa y se pone a 220 V. Idealmente lo suyo sería que el propio medidor midiera el voltaje e hiciera los ajustes, pero con una pinza amperimétrica poco más se puede hacer.

      Muy interesante el apunte sobre eagle-owl, aunque yo no soy el desarrollador y poco puedo hacer al respecto. De todas formas, si te apetece cacharrear tengo un fork de eagle-owl (https://github.com/jesjimher/eagle-owl) al que le he hecho unos cuantos cambios (entre ellos arreglar lo que comentas 🙂 ). Un día (cuando acabe de documentarla y pulirla) le dedicaré una entrada, pero básicamente he «adelgazado» el programa, eliminando el soporte para SQlite y mejorado un poco el fichero de configuración, de manera que se puede configurar que la salida vaya a un fichero de texto (o a una salida MQTT) sin tener que hacer malabarismos con screen y demás.

      • Gracias Jesús,
        No hay problema en esto, domino/controlo tanto la parte eléctrica como la de software.
        Estaría bien que el medidor «capturara» también tensión.
        Le echaré un vistazo al github.
        Por suerte ya estoy jubilado y de vez en cuando cacharreo un poco 😉

        Por cierto, alguien sabe/conoce si el módulo visualizador CM160 almacena y exporta también la temperatura ? (aparte de fecha, hora, intensidad, … ).

        Saludos cordiales
        Ernesto.

  2. Hola,

    sinceramente me parece «acojonante» e interesante el pedazo de blog. He seguido al pie de la letra el manual. Estoy pendiente que llegue el dichoso cm160 de AMAZON. La parte software está hecha y funcionando (puebas de inyectar manualmente datos a un emoncms local en la RPi3). Ahora faltará ver si los drivers para el cable usb funcionan y lee datos.

    Os estoy muy agradecido.

  3. Hola,

    otro detalle que ha hecho que me vuelva literalmente loco… En el script que envía datos al EMONCMS hay un problema. Creo que algo ha cambiado en la tabla SQL al extraer el último valor. Parece que hay un CR al final del valor cuando haces un CUT.

    wattios=$(echo $medida | cut -d, -f2)

    Si intentas inyectarlo tal cual a través de CURL te da error (de formato aunque no se ve por ser un carácter invisible).

    La solución después de muchas horas es:

    wattios=$(echo $medida | cut -d ‘,’ -f2 | tr -d ‘\r’)

    La función TR. Es decir, eliminar ese CR invisible pero existente.

    AHORA SI QUE SI…

    Saludos,
    Eddie

    • Me alegro que finalmente te funcione. De todas formas, yo acabé un poco harto de tener que andar ejecutando SQLs y demás para sacar los datos de consumo, y me tuneé un poco el eagle-owl para simplificarlo. En mi fork ya no hay nada de bases de datos SQlite, interfaz web y demás, y por no haber ni siquiera hay salida por pantalla. Se puede configurar que los datos de consumo vayan a un simple fichero de texto, o bien se envíen vía MQTT a algún sitio (si no voy mal emonCMS lo permite). Así se puede simplificar bastante todo lo que cuento aquí, porque ni hay consultas a BD (que con el tiempo son bastante pesadas, sobre todo si se ejecuta todo en una Raspberry Pi o similar), ni hay que hacer pirulas ejecutando el cm160 dentro de una sesión screen, porque todo se lee desde el fichero de texto (y si se usa la opción MQTT, ni eso).

      No es que lo haya probado mucho (dejé de usar el CM160 hace un tiempo), pero lo tuve en marcha unos meses e iba todo bien. Si quieres echarle un ojo, el fork está aquí: https://github.com/jesjimher/eagle-owl

    • Si no voy mal, lo de poner varias pinzas amperimétricas al CM160 es por si tienes una instalación trifásica, para poder leer las tres líneas. Pero el aparato las junta y envía un único valor, por lo que (salvo hackeada brutal del firmware del cacharro) no se podría usar para hacer mediciones de tres cables independientes.

  4. Hola,

    Jesús, te agradezco la respuesta. Voy a echarle un ojo al fork y lo probaré. He comprado por Amazon la segunda pinza (antes de que me contestaras). Ya os contaré.

    Lo que SI me gustaria seria suprimir el monitor y que la pinza envíe directamente los datos a la RPi por Radio 433Mhz con el adaptador RFM12B. ¿Alguien conoce algo de esto?

    • Pues lo único que se me ocurre es que te pongas algo tipo OpenEnergyMonitor. Es de la misma gente que el emoncms, y es básicamente un monitor al que le puedes enchufar hasta 4 pinzas independientes y enviar luego los datos con radio. Otra opción es que te enredes con un arduino o similar, pero eso ya son palabras mayores (te hará falta emisor para el arduino, receptor para la Raspberry, y software en los dos lados)

  5. Pingback: Shelly EM, el santo grial de los medidores de energía | No soy vago, soy eficiente

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.