OpenHAB en Raspberry Pi: Configurando RFXCOM (parte 4)

En esta entrada vamos a explicar como configurar el transceptor RFXtrx433 de RFXCOM para funcionar con openHAB.
Módulo RFXtrx433
En primer lugar hay que decir que el módulo RFXtrx433 es un emisor/receptor de señales RF en la banda de 433.92Mhz con conexión USB, que es capaz de decodificar muchos protocolos usados por interruptores, enchufes, estaciones meteorológicas, medidConfigurando el dispositivoores de energía… Entre todos esos protocolos se encuentra el usado por los enchufes que analicé aquí, aquí y aquí. El protocolo usado lo identifica como Impuls.

Configurando el dispositivo

Como se trata de un dispositivo USB cuando lo conectemos al equipo lo reconocerá como /dev/ttyUSB0 unas veces, otras como /dev/ttyUSB1… dependiendo de los dispositivos USB que tengamos en ese momento conectados. Para evitar ese baile de nombres vamos a definir una regla udev para que siempre lo tengamos como /dev/rfxcom.
Lo primero que hay que hacer es identificar nuestro dispositivo univocamente, que no haya posibilidad de error. Para ello usamos el comando:
udevadm info -a -p  $(udevadm info -q path -n /dev/ttyUSBx)
cambiando la x por el número que tenga nuestro dispositivo en el momento de conectarlo. Obtendremo un listado largo que contendrá algo así:
  ...
  looking at parent device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.2':
    KERNELS=="1-1.2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{devpath}=="1.2"
    ATTRS{idVendor}=="0403"
    ATTRS{speed}=="12"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="4"
    ATTRS{configuration}==""
    ATTRS{bMaxPower}==" 90mA"
    ATTRS{authorized}=="1"
    ATTRS{bmAttributes}=="a0"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{maxchild}=="0"
    ATTRS{bcdDevice}=="0600"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{serial}=="A1WR621M"
    ATTRS{version}==" 2.00"
    ATTRS{urbnum}=="16"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="RFXCOM"
    ATTRS{removable}=="removable"
    ATTRS{idProduct}=="6001"
    ATTRS{bDeviceClass}=="00"
    ATTRS{product}=="RFXtrx433"
  ...
De entre toda esta información del dispositivo debemos elegir algo que nos identifique al dispositivo. Se puede elegir el serial, o la combinación idVendor/idProduct… Lo más normal es elegir esto último.
Creamos el fichero /etc/udev/rules.d/10-local.rules con el siguiente contenido:
ACTION=="add",ATTRS{idVendor}=="0403",ATTRS{idProduct}=="6001",SYMLINK+="rfxcom"
Si desconectamos el dispositivo y lo volvemos a conectar nos debería aparecer el enlace /dev/rfxcom automágicamente enlazado al correspondiente /dev/ttyUSBx.
El addon RFXCom para openHAB utiliza la librería RxTx para acceder a los puertos serie del equipo, la cual no funciona demasiado bien con los dispositivos no estandares en /dev. Para solventar este inconveniente hay que decirle a openHAB que le diga a la librería RxTx que /dev/rfxcom es un dispositivo serie válido. Y ¿cómo lo hacemos? Fácil, hay que ir a los archivos start.sh y start_debug.sh para añadir en la última linea, la que inicia el programa con java… el siguiente parámetro:
-Dgnu.io.rxtx.SerialPorts=/dev/rfxcom
Tenéis mas informacion sobre la forma en que la librería RxTx detecta o lista los puertos serie del equipo aquí.

Primeras pruebas

Una vez que tenemos el dispositivo listo, y localizado, necesitamos hacer alguna prueba para ver si funciona correctamente. Para ello nos bajamos el software rfxcmd de aquí, y lo descomprimimos en una carpeta:
mkdir rfxcmd
cd rfxcmd
wget http://rfxcmd.googlecode.com/files/rfxcmd-v024.zip
unzip rfxcmd-v024.zip -d v024
cd v024
Al intentar ejecutarlo nos dice que falta la extensión Serial de python. La instalamos:
apt-get install python-seria

y continuamos con las pruebas poniendo el modulo en escucha continua:

./rfxcmd.py -d /dev/rfxcom

nos da la siguiente salida si todo ha ido bien:

RFXCMD version 0.24
------------------------------------------------
Received        = 0D 01 00 00 02 53 43 00 40 00 01 01 00 00
Date/Time        = 2013-10-02 12:22:50
Packet Length        = 0D
Packettype        = Interface Message
Subtype            = Interface response
Sequence nbr        = 00
Response on cmnd    = Get Status, return firmware versions and configuration of the interface.
Transceiver type    = 433.92MHz (Transceiver)
Firmware version    = 67
Display undecoded    = Off
Protocols:
Disabled        AE (433.92)
Disabled        Rubicson (433.92)
Disabled        FineOffset / Viking (433.92)
Disabled        RFU3
Disabled        RFU4
Disabled        RFU5
Disabled        RFU6
Disabled        Mertik (433.92)
Disabled        AD (433.92)
Disabled        Hideki/UPM (433.92)
Disabled        La Crosse (433.92/868.30)
Disabled        FS20 (868.35)
Disabled        ProGuard (868.35 FSK)
Enabled            BlindsT0 (433.92)
Disabled        BlindsT1/T2/T3 (433.92)
Disabled        X10 (310/433.92)
Disabled        ARC (433.92)
Disabled        AC (433.92)
Disabled        HomeEasy EU (433.92)
Disabled        Meiantech (433.92)
Disabled        Oregon Scientific (433.92)
Disabled        ATI (433.92)
Disabled        Visonic (315/868.95)

Configuración del addon RFXCom

Para que funcione el addon tenemos copiar el archivo jar en la carpeta de addons, y modificar en el fichero de configuración openhab.cfg el nombre del puerto serie que se usará para conectar con el dispositivo:

rfxcom.serialPort=/dev/rfxcom
Ahora podemos arrancar openHAB en modo depuración con start_debug.sh y ver los registros del addon, que serán algo parecido a esto:
root@raspberrypi:/opt/openhab# ./start_debug.sh
Launching the openHAB runtime in debug mode...
Listening for transport dt_socket at address: 8001
osgi> 08:49:54.236 DEBUG o.o.c.s.i.SchedulerActivator[:56] - Scheduler has been started.
08:49:54.866 INFO  o.q.impl.StdSchedulerFactory[:1175] - Using default implementation for ThreadExecutor
08:49:55.208 INFO  o.q.core.SchedulerSignalerImpl[:61] - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
08:49:55.215 INFO  o.quartz.core.QuartzScheduler[:243] - Quartz Scheduler v.2.1.7 created.
08:49:55.244 INFO  org.quartz.simpl.RAMJobStore[:154] - RAMJobStore initialized.
08:49:55.268 INFO  o.quartz.core.QuartzScheduler[:268] - Scheduler meta-data: Quartz Scheduler (v2.1.7) 'openHAB-job-scheduler' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 2 threads.
  Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

08:49:55.281 INFO  o.q.impl.StdSchedulerFactory[:1324] - Quartz scheduler 'openHAB-job-scheduler' initialized from specified file: './etc/quartz.properties'
08:49:55.287 INFO  o.q.impl.StdSchedulerFactory[:1328] - Quartz scheduler version: 2.1.7
08:49:55.297 INFO  o.quartz.core.QuartzScheduler[:534] - Scheduler openHAB-job-scheduler_$_NON_CLUSTERED started.
08:49:55.342 DEBUG o.o.c.core.ConfigDispatcher[:166] - Processing openHAB default configuration file '/opt/openhab/configurations/openhab_default.cfg'.
08:49:55.979 DEBUG o.o.c.core.ConfigDispatcher[:188] - Processing openHAB main configuration file '/opt/openhab/configurations/openhab.cfg'.
08:49:56.262 DEBUG o.o.c.internal.CoreActivator[:124] - UUID file already exists at '/opt/openhab/webapps/static/uuid' with content '0e3715df-824e-475d-8b46-539284ae5210'
08:49:59.126 DEBUG o.o.c.internal.CoreActivator[:146] - Created file '/opt/openhab/webapps/static/version' with content '1.3.1'
08:49:59.132 INFO  o.o.c.internal.CoreActivator[:92] - openHAB runtime has been started (v1.3.1).
08:49:59.521 DEBUG o.o.c.a.i.AutoUpdateActivator[:51] - AutoUpdate binding has been started.
08:50:20.086 DEBUG o.o.m.p.i.PersistenceModelActivator[:43] - Registered 'persistence' configuration parser
08:50:20.279 DEBUG o.o.c.t.i.TransformationActivator[:58] - Transformation Service has been started.
08:50:20.904 DEBUG o.o.i.g.internal.GCalActivator[:54] - Google Calendar IO has been started.
08:50:21.213 DEBUG o.o.i.m.i.MultimediaActivator[:54] - Multimedia I/O bundle has been started.
08:50:21.553 DEBUG o.o.i.s.i.DiscoveryServiceActivator[:47] - Discovery service has been started.
08:50:21.694 DEBUG o.o.i.t.mqtt.MqttService[:138] - Starting MQTT Service...
08:50:24.361 DEBUG o.o.m.i.i.ItemModelActivator[:44] - Registered 'item' configuration parser
08:50:26.163 DEBUG o.o.c.i.items.ItemRegistryImpl[:157] - Item provider 'GenericItemProvider' has been added.
08:50:35.668 INFO  o.o.m.c.i.ModelRepositoryImpl[:99] - Loading model 'casa.items'
08:50:39.939 DEBUG o.o.m.i.i.GenericItemProvider[:154] - Read items from model 'casa.items'
08:50:42.213 DEBUG o.o.m.s.i.SitemapModelActivator[:43] - Registered 'sitemap' configuration parser
08:50:43.127 DEBUG o.o.i.r.internal.RESTActivator[:53] - REST API has been started.
08:50:43.681 INFO  o.o.i.s.i.DiscoveryServiceImpl[:92] - mDNS service has been started
08:50:46.249 INFO  o.a.cpr.AtmosphereFramework[:742] - Installing BroadcastFilter class(es) org.atmosphere.client.FormParamFilter
08:50:46.531 INFO  o.a.cpr.AtmosphereFramework[:1118] - Auto detecting atmosphere handlers /WEB-INF/classes/
08:50:46.668 WARN  o.a.cpr.AtmosphereFramework[:814] - Missing META-INF/atmosphere.xml but found the Jersey runtime. Starting Jersey
08:50:47.025 INFO  o.a.cpr.AtmosphereFramework[:364] - Installed AtmosphereHandler org.atmosphere.handler.ReflectorServletProcessor mapped to context-path: /*
08:50:47.033 INFO  o.a.cpr.AtmosphereFramework[:1173] - Auto detecting WebSocketHandler in /WEB-INF/classes/
08:50:47.314 INFO  o.a.cpr.AtmosphereFramework[:1099] - Atmosphere is using async support: org.atmosphere.container.JettyAsyncSupportWithWebSocket running under container: jetty/8.1.3.v20120522 with WebSocket enabled.
08:50:47.324 INFO  o.a.cpr.AtmosphereFramework[:902] - Installed WebSocketProtocol org.atmosphere.websocket.protocol.SimpleHttpProtocol 
08:50:47.494 INFO  o.a.h.ReflectorServletProcessor[:126] - Installing Servlet com.sun.jersey.spi.container.servlet.ServletContainer
08:50:49.212 INFO  c.s.j.s.i.a.WebApplicationImpl[:791] - Initiating Jersey application, version 'Jersey: 1.11 12/09/2011 11:05 AM'
08:50:49.234 INFO  c.s.j.s.i.a.WebApplicationImpl[:802] - Adding the following classes declared in META-INF/services/jersey-server-components to the resource configuration:
  class org.atmosphere.jersey.AtmosphereResourceConfigurator
08:50:50.061 INFO  c.s.j.s.i.a.DeferredResourceConfig[:97] - Instantiated the Application class org.openhab.io.rest.internal.RESTApplication
08:50:52.236 INFO  o.o.m.c.i.ModelRepositoryImpl[:99] - Loading model 'casa.sitemap'
08:51:06.022 INFO  o.a.cpr.AtmosphereFramework[:589] - Installed Default AtmosphereInterceptor [Android Interceptor Support, SSE Interceptor Support, JSONP Interceptor Support]. Set org.atmosphere.cpr.AtmosphereInterceptor.disableDefaults in your xml to disable them.
08:51:06.029 WARN  o.a.cpr.AtmosphereFramework[:509] - No BroadcasterCache configured. Broadcasted message between client reconnection will be LOST. It is recommended to configure the HeaderBroadcasterCache.
08:51:06.043 WARN  o.a.cpr.AtmosphereFramework[:533] - Neither TrackMessageSizeInterceptor or TrackMessageSizeFilter are installed. atmosphere.js may receive glued and incomplete message.
08:51:06.049 INFO  o.a.cpr.AtmosphereFramework[:537] - HttpSession supported: false
08:51:06.055 INFO  o.a.cpr.AtmosphereFramework[:538] - Using BroadcasterFactory: org.atmosphere.cpr.DefaultBroadcasterFactory
08:51:06.061 INFO  o.a.cpr.AtmosphereFramework[:539] - Using WebSocketProcessor: org.atmosphere.websocket.DefaultWebSocketProcessor
08:51:06.066 INFO  o.a.cpr.AtmosphereFramework[:540] - Using Broadcaster: org.atmosphere.jersey.JerseyBroadcaster
08:51:06.085 INFO  o.a.cpr.AtmosphereFramework[:541] - Atmosphere Framework 1.0.4 started.
08:51:06.091 INFO  o.o.i.r.i.RESTApplication[:158] - Started REST API at /rest
08:51:06.106 DEBUG o.o.i.s.i.DiscoveryServiceImpl[:63] - Registering new service _openhab-server._tcp.local. at port 8080
08:51:08.742 DEBUG o.o.i.s.i.DiscoveryServiceImpl[:63] - Registering new service _openhab-server-ssl._tcp.local. at port 8443
08:51:11.929 INFO  o.o.u.w.i.s.WebAppServlet[:99] - Started Classic UI at /openhab.app
08:51:18.037 DEBUG o.o.m.r.i.RuleModelActivator[:62] - Registered 'rules' configuration parser
08:51:18.151 DEBUG o.o.m.r.i.engine.RuleEngine[:98] - Started rule engine
08:51:22.341 DEBUG o.o.b.r.i.RFXComActivator[:54] - RFXCOM binding has been started.
08:51:22.538 DEBUG o.o.b.r.i.RFXComConnection[:68] - Activate
08:51:22.551 DEBUG o.o.b.r.i.RFXComConnection[:94] - Configuration updated, config true
08:51:22.562 INFO  o.o.b.r.i.RFXComConnection[:127] - Connecting to RFXCOM [serialPort='/dev/rfxcom' ].08:51:22.690 DEBUG o.o.m.i.i.GenericItemProvider[:312] - Start processing binding configuration of Item 'Salon_Lampara (Type=SwitchItem, State=Uninitialized)' with 'RFXComGenericBindingProvider' reader.
08:51:22.769 DEBUG o.o.m.i.i.GenericItemProvider[:312] - Start processing binding configuration of Item 'Cargador_Aspiradora (Type=SwitchItem, State=Uninitialized)' with 'RFXComGenericBindingProvider' reader.
08:51:22.782 DEBUG o.o.m.i.i.GenericItemProvider[:312] - Start processing binding configuration of Item 'Dormitorio_TV (Type=SwitchItem, State=Uninitialized)' with 'RFXComGenericBindingProvider' reader.
08:51:22.796 DEBUG o.o.m.i.i.GenericItemProvider[:312] - Start processing binding configuration of Item 'Cocina_Cafetera (Type=SwitchItem, State=Uninitialized)' with 'RFXComGenericBindingProvider' reader.
08:51:22.813 DEBUG o.o.m.i.i.GenericItemProvider[:312] - Start processing binding configuration of Item 'Salon_TV (Type=SwitchItem, State=Uninitialized)' with 'RFXComGenericBindingProvider' reader.
RXTX Warning:  Removing stale lock file. /var/lock/LCK..rfxcom
08:51:22.897 DEBUG o.o.b.r.internal.RFXComBinding[:78] - Activate
08:51:22.998 DEBUG o.o.b.r.i.RFXComConnection[:133] - Reset controller
08:51:23.013 DEBUG o.o.b.r.i.c.RFXComSerialConnector[:172] - Data listener started
08:51:24.129 DEBUG o.o.b.r.i.RFXComConnection[:161] - Data received:
Raw data = 0D0100010253431F8FFD01010000
 - Packet type = INTERFACE_MESSAGE
 - Seq number = 1
 - Sub type = INTERFACE_RESPONSE
 - Command = GET_STATUS
 - Transceiver type = _443_92MHZ_TRANSCEIVER
 - Firmware version = 67
 - Hardware version = 1.1
 - Undecoded packets = false
 - RFU6 packets = false
 - RFU5 packets = false
 - RFU4 packets = true
 - RFU3 packets = true
 - FineOffset / Viking (433.92) packets = true
 - Rubicson (433.92) packets = true
 - AE (433.92) packets = true
 - BlindsT1/T2/T3 (433.92) packets = true
 - BlindsT0 (433.92) packets = false
 - ProGuard (868.35 FSK) packets = false
 - FS20 (868.35) packets = false
 - La Crosse (433.92/868.30) packets = true
 - Hideki/UPM (433.92) packets = true
 - AD (433.92) packets = true
 - Mertik (433.92) packets = true
 - Visonic (315/868.95) packets = true
 - ATI (433.92) packets = true
 - Oregon Scientific (433.92) packets = true
 - Meiantech (433.92) packets = true
 - HomeEasy EU (433.92) packets = true
 - ARC (433.92) packets = false
 - X10 (310/433.92) packets = true
08:51:27.282 DEBUG o.o.b.r.i.RFXComConnection[:161] - Data received: - AC (433.92) packets = true
Raw data = 0A520700320E00FE300140
 - Packet type = TEMPERATURE_HUMIDITY
 - Seq number = 0
 - Sub type = WT260_WT260H_WT440H_WT450_WT450H
 - Id = 12814
 - Temperature = 25.400000000000002
 - Humidity = 48
 - Humidity status = COMFORT
 - Signal level = 4
 - Battery level = 0
De momento esto es todo por hoy… En la siguiente entrada iremos un poco mas allá: configuraremos los enchufes RF y crearemos un pequeño sitemap con unos cuantos items para gestionarlo todo por web o con el teléfono móvil. Espero que os guste 🙂
¡Un saludo a todos!
8 comentarios

Añadir un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

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