VisualDomo. Entendiendo el problema (I)

viernes 20 de junio de 2014 por Alfredo

Como en cualquier otro proyecto, el primer paso a realizar es conocer bien el problema al que nos enfrentamos y definir correctamente adonde queremos llegar. Obviamente en nuestro contexto el protagonista principal es ODControl.

Controlador IP

De manera sencilla, un ODControl es un controlador IP. Un controlador es un sistema electrónico que, como su nombre indica, permite controlar un conjunto dispositivos eléctricos que puede ser conectados a él, para lo cual dispone de una serie de puertos ya sean por una parte de entrada o salida y por otra, analógicos o digitales.

El hecho de ser IP lo convierte además en un dispositivo que puede ser conectado a un red IP, posibilitando el acceso desde otro dispositivos de la red y,  mediante un navegador web, una consola ssh o cualquier otro método, acceder a las funciones que disponen sus entradas y salidas.

Por ver un ejemplo gráfico, el esquema de una supuesta instalación completa (y básica) para controlar un sistema de iluminación podría ser:

esquema-controlador

El controlador IP (C-IP) está conectado mediante Ethernet a un modem-router que, por una parte, da salida/entrada a internet y por otra funciona como punto de acceso WiFi. Además el C-IP conecta una de sus salidas a un relé (R1) que hace las funciones de interruptor y que a su vez estará conectado a la fase y al punto de luz a controlar. Dicho control (apagado/encendido) se podrá realizar desde el dispositivo móvil.

ODControl

ODControl es el controlador IP que comercializa OpenDomo Services S.L.. En el momento de desarrollo del proyecto, OpenDomo Services S.L. tiene disponibles dos versiones (la 1 y 2).

ODControl-picture

Para nuestro objetivo, no es necesario entrar en detalle en varias de las especificaciones técnicas de cada una, si bien es interesante saber las funcionalidades de ambos productos, especialmente en la versión 2 que es en la que nos centraremos en un primer momento.

 

ODControl 1

ODControl 2

Parámetro

Valor

Parámetro

Valor

Número de salidas digitales

8

Número de salidas digitales

8

Número de entradas digitales

8

Número de entradas digitales

8

Número de entradas analógicas

8

Número de entradas analógicas

2

Número de salidas analógicas

0

Número de salidas analógicas

2

Bus IP (RJ45)

1

Bus IP (RJ45)

1

Protocolos

UDP, HTTP

Protocolos

UDP, HTTP

Puertos virtuales

48

Puertos virtuales

61

 

Obviamente, el número de puertos es limitado luego según las necesidades de la instalación puede ser necesario utilizar para cada una de las localizaciones más de un ODControl.

La configuración de cada ODControl se realiza accediendo mediante un navegador web a la dirección IP asignada al controlador (por defecto 169.254.0.15), lo que da acceso a la aplicación Configurator. Desde ella es posible visualizar el estado de los puertos digitales de salida y de entrada, pero también podremos configurar los puertos, ejecutar comandos o realizar tareas de mantenimiento (cambio de IP’s, contraseñas, nombre, etc)

Para simplificar la configuración, ODControl permite el uso de plantillas predefinidas. El usuario puede crear las que desee y posteriormente replicarlas en otros de sus ODControl o descargar desde el sitio web de OpenDomo aquellas que le resulten interesantes y que otros usuarios han compartido. Así, por ejemplo, si deseamos una instalación para el control de 8 puntos de luz (plantilla que podemos encontrar en la web) la configuración de los puertos (asignar nombres a los puertos de entrada, activarlos… ) simplemente se reduce a cargar la plantilla.

Además de los puertos físicos ODControl también posee puertos virtuales. Estos puertos permite el almacenamiento de manera temporal o persistente de valores para ser utilizados posteriormente. El valor que guardan puede venir calculado por alguna operación booleana o aritmética entre otros dos puertos, por la finalización de un disparador (día, fecha o cuenta atrás) o el resultado de una operación de comparación donde el puerto virtual se activará (1) en caso de que la condición sea cierta.

Por último, el ODControl posee una gran cantidad de comandos que puede ser ejecutados desde el propio Configurator o mediante llamadas externas al puerto 81 utilizando el protocolo HTTP. Este tipo de comunicación va autenticada pero no cifrada, por lo que únicamente resulta conveniente su uso en entornos controlados. Como se verá a lo largo del desarrollo este va a ser el principal mecanismo de comunicación entre VisualDomo y ODControl.

+Info: Comandos ODControl
+Info: OpenDomo Lightweight Encryption Protocol (ODLEP)

Un nuevo proyecto: VisualDomo

viernes 13 de junio de 2014 por Alfredo

logoODS

Tras unos meses de sequía por compromisos varios, en los próximos meses voy a desarrollar un nuevo proyecto: VisualDomo,una aplicación para dispositivos móviles que permite el control de manera visual de dispositivos ODControl.

ODControl es un controlador con posibilidad de conexión IP desarrollado por la empresa OpenDomo Services S.L.. Este controlador permite actuar sobre diferentes dispositivos electrónicos gracias a varios puertos tanto de tipo analógico como digital, lo que lo hace muy adecuado para el control de instalaciones domóticas.

El objetivo del proyecto es facilitar al usuario el manejo de su instalación domótica, permitiendo definir su localización mediante la carga de planos y controlar cada uno de los aparatos conectados a los puertos de manera sencilla.

Las propia idiosincracia del proyecto implica la posibilidad de abarcar el mayor número posible de dispositivos móviles existentes, no únicamente por configuración física (tabletas o móviles) sino también por la variedad de plataformas existentes. Además los productos OpenDomo están en constante evolución, lo que hace complicado el mantenimiento de varias aplicaciones. Por todo ello se ha decidido utilizar para el desarrollo el framework PhoneGap/Cordova, que permite mediante tecnologías web (HTML5+JS+CSS3) crear un único código fácilmente compilable en distintas plataformas.

Además de su valor empresarial, el proyecto también tiene carácter académico y educativo ya que se presenta como Trabajo Final del Master Universitario de Software Libre, impartido por la Universitat Oberta de Catalunya (UOC).

La idea es  crear durante estos meses una serie de posts que hablen sobre el proceso de creación, centrándome especialmente en la parte técnica.

+Info: opendomo
+Info: ODControl
+Info: cordova
+info: Univesitat Oberta de Catalunya

Error de ejecución JOGL con NetBeans

viernes 17 de enero de 2014 por Alfredo

 

jogljava

Una de las mejores maneras, sino la mejor, de poder utilizar OpenGL en Java es el uso de la librería JOGL. En la sencillez de su planteamiento radica su potencia, ya que se podría decir lo único que hace es mapear la gran mayoría de las funciones nativas de OpenGL de manera que puedan ser utilizadas de la misma manera que en C o C++ pero en Java. Por ejemplo, lo que en C podría ser el dibujo de una línea:

glBegin(GL.GL_LINES);
    glVertex3f(1.0f,0.0f,0.0f);
    glVertex3f(4.0f,1.0f,0.0f);
glEnd();

en Java quedaría como:

GL gl = drawable.getGL();

gl.glBegin(GL.GL_LINES);
    gl.glVertex3f(1.0f,0.0f,0.0f);
    gl.glVertex3f(4.0f,1.0f,0.0f);
gl.glEnd();

Desde entornos como NetBeans podemos acceder a plugin que además de proporcionar la librería, instalan asistentes, ejemplos e incluso componentes preparados para que se pueda dibujar sobre ellos directamente como es GLCanvas. Generalmente su uso es sencillo (independientemente de la complejidad de OpenGL), pero en ocasiones surgen problemas de ejecución debidos a la no localización de la librería nativa de OpenGL con la que se hace el mapeo. En estos casos el error que suele aparecer es similar a:

java.lang.UnsatisfiedLinkError: no gluegen-rt in java.library.path

en el que se nos indica que no se ha podido enlazar con la librería nativa (es decir, la de cada SO) correspondiente. La solución suele venir por la indicación de manera explícita a la máquina virtual de donde está ubicada esa librería nativa. En ese caso lo primero es localizar su ubicación. Si estamos trabajamos con NetBeans y hemos instalado el plugin de JOGL, las liberias se suelen encontrar en una carpeta oculta dentro de la carpeta del usuario. Por ejemplo en Linux en /home/usuario/.netbeans/7.0 y allí distribuidas por librería y plataforma. En este caso (Linux sobre amd64) el parámetro necesario para la ejecución correcta sería

-Djava.library.path=/home/usuario/.netbeans/7.0/gluegen-runtime/gluegen-rt.jar-natives-linux-amd64

Este parámetro puede ser añadido desde Run/Set Project Configuration/Customize y en esa ventana dentro de las opción VM Options. Aún así es probable que siga apareciendo el error :(. Si es así lo más probable sea que en el fichero de propiedades del proyecto la plataforma no este bien configurada (cosa muy habitual si trabajamos en plataformas distintas). Para ello no hay más que editar nbproject/private/config.properties y cambiar la propiedad natives.platform por aquella que en esos momentos estemos utilizando.

+info: JOGL
+info: OpenGL pack for NetBeans 

 

Firmando aplicaciones Android

jueves 18 de julio de 2013 por Alfredo

Todas las aplicaciones que vayan a ser instaladas en un Android (ya sea en un terminal o el emulador) deben estar firmadas. Esto es así porque Android utiliza esa firma para identificar a la aplicación que está realizando cualquier tipo de petición ya sea al sistema o a otras aplicaciones.

En principio se podía pensar que para poder firmar Google o alguna entidad nos tendría que dar algún tipo de certificado que «confirmara quien somos» (algo así como la FNMT en España, que nos proporciona el DNIe), pero no hace falta: las aplicaciones Android pueden ser firmadas con certificados personal, es decir, creados por nosotros mismos.

El proceso de firmado es sencillo, de hecho lo hacemos cada vez que compilamos. En modo depuración, Eclipse firma con unas firmas públicas todo los apk que genera para que así puedan ser instalados en el emulador. Esas claves se encuentran en (en Linux y MacOSX) ~/.android/debug.keystore y las genera cuando se compila por primera vez.

ATENCIÓN: Es posible cambiar la ubicación del fichero de almacén de claves (debug.keystore) desde  Eclipse/ADT, yendo a Windows > Preferences > Android > Build.

ATENCIÓN: si la firma caduca, sólo tenéis que borrar el fichero y Eclipse generará otro.

Esta firma es de acceso público (las contraseñas son «Android» y el alias de la clave es: «androiddebugkey») por lo que a la hora de distribuir la aplicación, debes generarte tu propia firma.

¿Cómo generar mi clave?

Hay dos formas: una usando la herramienta de línea de comandos keytool (tal como se explica aquí) y otra con el  propio Eclipse. Para ello vamos al ficheros Manifest.xml de nuestro proyecto y en la pestaña Manifest, pinchamos sobre la opción Uses the Export Wizard.

Esta acción arranca el asistente para la exportación de aplicaciones Android, que nos va a permitir utilizar nuestras claves ya guardadas o crear unas nuevas. Las claves se agrupan en lo que se llama almacén de claves o keystore. Como el objetivo es crear nuestra clave, en la primera ventana seleccionamos Create new keystore, seleccionamos la ubicación de nuestro almacén y le ponemos una contraseña.

¿Hay que firmar cada aplicación con una firma distinta?

No es necesario ni recomendable. Lo más habitual es firmar todas las aplicaciones que vayas desarrollando con la misma firma. Hay varias razones. Una es la la creación de actualizaciones: todas las versiones de una aplicación deben ir firmadas con la firma, o no se podrán actualizar. Además,  si queremos conectar varias de nuestras aplicaciones, la única manera será la utilización de la misma firma en todas ellas.

¿Qué es el periodo de validez?

Indica la caducidad de la firma, pero sólo a efectos de instalación. Es decir, una vez instalada la aplicación aunque la firma caduque la aplicación seguirá funcionando perfectamente. A la hora de indicar el tiempo, hay que pensar en la vida presumible de la aplicación (con sus versiones) y de todas aquellas que vayamos a firmar con la misma clave. Es por eso que se recomienda duraciones largas.

ATENCIÓN: Si estás pensando en subirla a Google Play, la firma tiene que caducar obligatoriamente después del 22/10/2033.

Como hacer una calculadora simple en Android (y II)

domingo 24 de junio de 2012 por Alfredo

En la entrada anterior estuvimos diseñando la layout de nuestra calculadora. Ahora toca hacer que funcione 🙂

Código

Aparte del algoritmo básico de la calculadora, lo principal es darle funcionalidad a los distintos botones. Para ello vamos a hacer uso de los listeners.

Un listener (o «escuchador» en español) es un objeto de una clase que implementa un interfaz que «le obliga» a tener una función que se ejecutará en el caso de que se produzca un evento determinado. Dicho así queda confuso, así que lo mejor es implementarlo para nuestra calculadora.

Lo primero será crear para cada uno de los recursos de la calculadora una variable de control, por ejemplo:

private EditText _edit;
private Button _b1;

Lo siguiente es asignar a cada una de estas variables, los objetos de cada uno de los recursos que ya han sido creados por la función setContentView(R.layout.main);. Para ello utilizamos la función miembro de la clase Activity findViewById, que busca un recurso por su identificador. En nuestro caso, y siguiendo con los dos recursos anteriores;

_edit = (EditText)findViewById(R.id.editTextos);
_b0 = (Button)findViewById(R.id.button0);

Y por fin, el listener. En nuestro caso tenemos 16 botones, pero 10 de ellos tiene un funcionalidad similar: queremos que al pulsar, aparezca en la casilla de edición el número que aparece como texto en el botón. Es por esto, que en vez de hacer 10 listeners para cada uno de los botones, optamos por la creación de un único listener común a todos ellos:

View.OnClickListener lsBoton = new View.OnClickListener() {
     @Override
     public void onClick(View arg0) {
         _edit.setText(_edit.getText()+((Button)arg0).getText().toString());
     }
};

Analicémoslo:

View.OnClickListener, es un interfaz que han de implementar aquellas clases que vayan a crear objetos listeners. Para no crear la clase ya que solo va a tener un uso mu concreto, hacemos un new del interfaz, pero definiendo la función que el listener nos «obliga» a tener, en este caso OnClick(). Dicha función recibe como argumento la View del recurso sobre el que se pincha (arg0), así que son un casting  podemos obtener de manera sencilla el valor del rótulo del botón.

Sólo nos queda asociar este listener a nuestro botones:

_b1.setOnClickListener(lsBoton);

Sólo nos queda repitir este paso para todos los botones numéricos, repitir un proceso similar con los botones de las operaciones y aplicar la lógica de la calculadora.

Extra

Existe otras dos  posibilidades para asignar el listener al botón.

La primera es definirlo desde el propio layout. Simplemente se le añade la propiedad android:onClick, dándole como valor la función a la que se llamará en el caso de producirse el evento Click. Por ejemplo:

android:onClick="funcion"

La segunda es hacer que la propia Activity implemente el interfaz View.OnClickListener, con lo cual será necesario definir la función onClick en su interior, pero podríamos asignar el objeto this como valor a las funciones de asignación de listeners

_b1.setOnClickListener(this);
class Calculadora extends Activity implments View.OnClickListener {
     ...
     @Override
     public void onClick(View v) {
           ...
     }
     ...
}

Puedes acceder al código de la calculadora en github
+ Info en | Android developers

 

Como hacer una calculadora simple en Android (I)

jueves 21 de junio de 2012 por Alfredo

En estas dos entradas vamos a crear una primera aplicación en Android, consistente en una calculadora que únicamente procese números enteros. La idea es manejar el TableLayout y los listeners.

Creando el proyecto

Para empezar desde Eclipse, seleccionamos File/New/Android Project… Le damos como nombre de proyecto Calculadora, elegimos una de las plataformas que tenemos instaladas y en la última ventana elegimos el nombre del paquete al que pertenece la aplicación. Este nombre es importante, ya que será el nombre completo con el que la aplicación será conocida, y podría entrar en conflicto con otras aplicaciones si el nombre se repitiera. En este caso ponemos: edu.uhuru.moviles.android.Calculadora

Creando el layout

Vamos al fichero main.xml que está dentro de la carpeta res. En ese fichero se define el diseño de la actividad principal (y única en nuestro caso). Desde el diseñador gráfico incluímos un TableLayout.

Nota: en muchas ocasiones puede ser interesante insertar los layouts en la ventana de Outline, que muestra el árbol de recursos de la Activity

Los layouts son los elementos invisibles pensando para controlar la distribución, posición y dimensiones de los controles que van en su interior. Hay varios disponibles, pero en este nos decidimos por un TableLayout, que organiza a sus hijos en forma de tabla. Se compone de elementos TableRow (filas). Cada fila puede contener cero o mas celdas. El ancho de la columna viene normalmente definido por el ancho de la celda más ancha, aunque siempre es posible aplicar algún atributo para jugar con el tamaño de las columnas.

Por defecto se nos crean 4 filas, así que añadimos una más simplemente arrastrando desde la paleta de controles una TableRow. Una vez añadida, procedemos a ir incorporando a cada fila los distintos recursos:

  1. Fila 1: 1 EditText
  2. Fila 2: 4 Buttons
  3. Fila 3: 4 Buttons
  4. Fila 4: 4 Buttons
  5. Fila 5: 4 Buttons

El siguiente problema es como hacer «crecer» el EditText para que ocupe las 4 columnas. Para ello utilizamos la propiedad  layout_span=»4″, que al igual que en HTML, nos expande la columna para que ocupe 4 columnas. Para colocar estas propiedades es casi más recomendable (y rápido) dejar el editor visual y trabajar directamente sobre el HTML:

<EditText  android:id="@+id/editTextos" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_span="4" />

A continuación hay que ajustar los botones, para que se repartan de manera equitativa por todo el ancho de la actividad. Para ello utilizamos la propiedad android:stretchColumns=»*», que indica que columnas (en nuestro caso todas, *) pueden expandirse para absorver el espacio libre dejado por las demás columnas a la derecha de la pantalla. De esta forma, los botones aparecerán ya compensados. O al menos aparentemente. El problema vendría si alguno de los botones tuviera más de un caracter (por ejemplo si pusiéramos  +/- , MR …). En ese caso, todos los botones de la columna de ese botón aumentaría su ancho. El problema se soluciona de una manera simple mediante  el uso de la propiedad  android:layout_weight=»1″.

Esta propiedad indica el peso relativo que ha de tener ese recursos con sus hermanos. Por ejemplo, si a 3 de los botones les pusieramos android:layout_weight=»1″ y al cuarto android:layout_weight=»2″, este último sería el doble de ancho que el primero. Como en nuestro caso queremos tener todos del mismo ancho indicamos android:layout_weight=»1″.

Por otra parte, necesitamos indicar al renderizador que el ancho de los botones no ha de ir en función de su tamaño «natural» (cuanto más texto tenga dentro, más grande). Por ello cambiaremos el ancho de wrap_content a 0dip. Juntando cada una de estas dos opciones en uno de los botones (por ejemplo el 7) quedaría:

<Button android:id="@+id/button7"
         android:layout_width="0dip"
         android:layout_height="wrap_content"
         android:text="7"
         android:layout_weight="1" />

Por último, para darle los últimos detalles estéticos, vamos a justificar el texto del EditText a la derecha, a no permitir la edición y a ocultar el cursor. Para ello, modificamos el EditText añadiendo:

<EditText  android:id="@+id/editTextos" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_span="4" 
            android:editable="false"
            android:gravity="right"
            android:cursorVisible="false" />

 

Programar dispositivos Android: Herramientas e instalación.

jueves 24 de mayo de 2012 por Alfredo

Lo primero es descargarse e instalar las herramientas necesarias Herramientas:

  1. JDK 6: Se puede encontrar aquí para los 3 SO principales.
  2. Eclipse. Va a ser nuestro entorno de desarrollo (IDE). Desde el sitio de descargas es posible bajar varias versiones. En principio con la Eclipse Classis es más que suficiente.
  3. SDK Android. Se puede descargar de aquí y posteriormente descomprímirlo en un carpeta. En este paquete realmente sólo se encuentran las herramientas básicas que proporciona el SDK. Para empezar a trabajar es necesario descargarse al menos una plataforma de Android y las herramientas de plataforma.
  4. Instalar ADT (o lo que es lo mismo Android Development Tools). ADT es un plugin para Eclipse que ayuda al desarrollo de aplicaciones para Android. Para ello dentro de Eclipse, en la opción Working with que se encuentra en Help / Install new software… se debe añadir la URL: https://dl-ssl.google.com/android/eclipse/. Una vez añadida se conectará y mostrará en la parte inferior la entrada Developer Tools. Hay que seleccionarla y darle a siguiente. Este último paso puede dar problemas de dependencias por varias razones: a)  si estás con una versión relativamente antigua de Eclipse (Galileo – 3.5). Para evitar este problema añade la url http://download.eclipse.org/releases/galileo en Available Software Sites dentro del menú Window / Preferences. b) Si has instalado Eclipse mediante los paquetes que te ofrece tu distribución de Linux. En ese caso has de incluir en Windows / Preferences / Install/Update / Available Software Repositories, el repositorio de tu versión de Eclipse. Por ejemplo, https://download.eclipse.org/releases/indigo
  5. El siguiente paso es la instalación de las plataformas. Para ello lo primero es indicarle a Eclipse donde se encuentra el SDK descargado en el paso 3, lo que se hará desde Window / Preferences / Android. Una vez indicada la ruta, dentro en Window /SDK and AVD Manager encontraremos las opciones para cargar las plataformas. En available packages se encuentran los paquetes disponibles para la instalación, mientras que en Virtual Devices y en installed packages están emuladores y plataformas instalados respectivamente. Una vez instaladas las plataformas, instalar un emulador es muy sencillo.

Te recomiendo que utilices la última versión de Eclipse (en el momento de escribir estas líneas es Indigo, la 3.7) para evitar problemas. Si desde tu distribución Linux no tienes aún acceso a ella, puedes seguir este pequeño tutorial, que te ayudará a instalarla. Fácil ¿verdad?. Ahora ya está todo preparado para poder empezar a programar.

Configuración y uso de rsync contra un Ubuntu Server

martes 3 de enero de 2012 por Alfredo

rsync es una aplicación que se puede encontrar en vuestros sistemas Linux, MacOS o  Windows y que permite sincronizar archivos y directorios entre dos máquinas de una red o entre dos carpetas de una misma máquina. Su uso es sencillo y es ideal para mantener al día copias de elementos utilizados por varias personas,  hacer copias de seguridad de nuestros datos de manera rápida y segura o mantener actualizada nuestra página web.
Puede funcionar de dos maneras:

  1. Instalando un daemon (un servicio) en nuestro servidor (donde tenemos los elementos a sincronizar) al cual accederemos mediante el protocolo rsync.
  2. Mediante un terminar remoto como SSH

Caso 1.El objetivo es instalar un daemon en nuestro servidor que atienda las peticiones de sincronización. Para ello los pasos a seguir son:

1.a) Instalar rsync. En general viene instalado de serie, y más en una versión server de Ubuntu, pero si no fuera así simplemente instálalo con Synaptic o mediante:

sudo apt-get install rsync

1.b) Hay que crear el fichero de configuración del daemon «/etc/rsyncd.conf». En él definimos las caracterísiticas generales de la conexión, así como las de cada uno de los módulos o,  para definirlo mejor, las posibles ubicaciones de sincronización. El fichero tendrá una forma similar a esta

max connections = 2
log file = /var/log/rsync.log
timeout = 300

    [nombremodulo1]
    comment = Carpeta de documentos personales sobre Linux
    path = /carpeta/sobre/la/que/sincronizo/los/documentos/personales
    read only = yes
    list = yes
    uid = usuario1
    gid = usuario1  
    auth users = usuario1
    secrets file = /etc/rsyncd.secrets

    [nombremodulo2]
    comment = Carpeta de documentos Uhuru
    path = /carpeta/sobre/la/que/sincronizo/los/documentos/uhuru
    read only = yes   
    list = yes   
    uid = nobody
    gid = nogroup   
    auth users = usuario1 usuario2
    secrets file = /etc/rsyncd.secrets

Al principio del fichero se definen aquellas características generales de la conexión. En este caso aparecen el número de conexiones simultáneas, donde se va a ubicar el fichero log y el tiempo máximo de espera. En esta parte es posible indicar también algunas de las características que aparecen en los módulos para que todos ellos la hereden (salvo que se redefinan dentro de uno en concreto). Por ejemplo, en el código anterior, podríamos haber escrito en las características generales la configuración de secrets file o la opción list, ya que su valor es común para todos los módulos.

A continuación aparecen la definición y características del módulo. Los elementos más importantes son:

  • comment: un comentario sobre que se sincroniza con ese módulo.
  • path: el camino completo de la ubicación.
  • uid: nombre del usuario con el que rsync realizar las acciones.
  • gid: grupo con el que rsync realizará las acciones.
  • auth users: usuarios a los que se les está permitido la sincronización. Estos usuario en principio no tiene porque coincidir con ningún usuario del sistema.
  • secrets file: lo vemos en el apartado siguiente.

1.c)  Crear el fichero «/etc/.rsyncd.secrets». Este fichero almacena parejas usuario:contraseña, que hacen relación a los usuarios definidos en el fichero «/etc/rsyncd.conf». En nuestro caso podría ser algo como esto:

usuario1:mipassword1
usuario2:mipassword2

Obviamente este fichero, al ser texto plano,  ha de ser protegido contra «mirones», ya que en caso contrario nuestras contraseñas quedan fácilmente accesibles. Es más rsync ni siquiera funcionará si no asignamos unos permisos adecuados a este fichero. Para ello:

sudo chmod 600 /etc/rsyncd.secrets

Es decir, el propietario debe ser el root y sólo puede ser leído por él.

1.d) Una vez configurado, sólo nos queda arrancarlo. Para ello lo mejor es utilizar xinetd, otro de los demonios que podemos encontrar en linux y que permite gestionar las conexiones de otros demonios bajo demanda.

Para ello lo primero es instalarlo (si es que no lo tienes aún):

sudo apt-get install xinetd

1.e) Configurar xinetd. Si no existe crea el fichero «/etc/xinetd.d/rsync» con el contenido siguiente.

service rsync
{
    disable = no
    socket_type = stream
    wait = no
    user = root
    server = /usr/bin/rsync
    server_args = --daemon
    log_on_failure += USERID
}

1.f) Comprobar el puerto por el que el servidor rsync escuchará. Para ello ves al fichero»/etc/services» y comprueba que la siguiente línea existe y no está comentada:

rsync 873/tcp

1.g) Reinicia el daemon xinetd. Para ello:

sudo /etc/init.d/xinetd restart

1.h) Ya tenemos el servidor funcionado. ¿Como lo usamos?. Sencillo, en local ejecutamos:

rsync -v --recursive --times --perms --links --delete /mi/carpeta/personal/local rsync://[email protected]/nombremodulo1

donde estamos haciendo una sincronización recursiva, preservando fechas y permisos de los archivos origen, incluyendo vínculos, borrando archivos que fueron borrados en el directorio origen. Todo ello desde un directorio origen /mi/carpeta/personal/local y utilizando el protocolo rsync contra el servidor miservidor, con el usuario1 y utilizando el módulo nombremodulo1

Caso 2. La segunda opción consiste en la utilización del terminal remoto seguro ssh.

El proceso de creación de clave pública y privada y configuración del terminal escapa de este tutorial.

En este caso no es necesaria la configuración del demonio en el servidor, tan sólo que rsync esté instalado en él. Para ejecutar la sincronización:

rsync -v --rsh=/usr/bin/ssh --recursive --times --perms --links --delete /mi/carpeta/personal/local [email protected]:carpeta/destino/servidor

Java en aplicaciones para móviles

lunes 11 de abril de 2011 por Alfredo

Acabábamos el post anterior comentando que el uso de J2Me podía hacer que la programación para ciertas plataformas se realizara de manera común.  ¿Común? bueno, si, pero no tanto, ya que no todos estos dispositivos tiene el mismo soporte de J2ME. ¿la razón? Tal vez lo primero sea definir que es exactamente J2ME.

J2ME, o ahora mismo llamada Java ME,  es una de los componentes de la llamada plataforma Java  junto con Java EE y Java SE. Su objetivo es proporcionar una serie de API’s para el desarrollo de aplicaciones en dispositivos con recursos limitados como PDA’s, coches, móviles, electrodomésticos… Es decir, el campo de dispositivos que abarca J2ME es muy grande y con unas características de hardware muy variadas.

Es por ello que Java ME se divide en las llamadas configuraciones. Existen dos: la CDC (pensada principalmente para domótica o automóviles) y la CLDC (Connected Limited Device Configuration), que es la que está en la mayoría de los móviles. Cada una de ellas proporciona unas API especiales para cada tipo de hardware.

Pero hay más. En cada configuración existen los llamados «profiles» (perfiles). Estos nos definen características concretas, por ejemplo la interfaz de usuario. Para CLDC hay tres perfiles: DoJa, pensado para móviles japoneses, IMP (para móviles sin interfaz de usuario) y MIDP (Mobile Information Device Profile) que es una versión del anterior pero con interfaz de usuario.

Es decir, que dentro de Java ME trabajaremos con la configuración CLDC  y el perfil MIDP.

Pero claro, no todo podía ser tan bonito 🙂 . A partir de aquí empiezan las particularizaciones. Cada dispositivo móvil puede incluir soporte para distintas APIs opcionales. Por ejemplo, en función del modelo sobre el que queramos programar podemos necesitar una API para el manejo de la geolocalización, de la cámara, del bluetooth,…  o de una interfaz gráfica personalizada.

¿Que ocurre al final? Pues que cada fabricante realiza sus propias implementaciones de J2ME, basándose siempre en la original de Oracle, pero pensadas en particular para sus dispositivos. De esta manera hay funcionalidades que pueden existir en una versión y en otra no, o que aún existiendo, tengan comportamientos distintos.

A día de hoy la última versión del CLDC es la 1.1 y del MIDP la 2.0.

 

Uploadify: Subida de archivos con jQuery

jueves 31 de marzo de 2011 por Carlos

La última página web que hemos creado en Uhuru Labs, Navarro y Soler CAD-PLM Software, requería una sección donde los usuarios de la web pudieran mandar a nuestro cliente ficheros de un tamaño considerable. Teniendo este requerimiento empezamos a investigar por la red buscando algún uploader que no fuese el simple formulario de subida de ficheros, sino que proporcionara algo más, aparte de ser fácilmente configurable.

Enamorados como estamos de jQuery y de todo lo que lleva consigo esta potente librería en javascript, buscamos algún uploader que estuviera hecho a partir de jQuery y encontramos Uploadify. Un pequeño vistazo por encima nos hizo darnos cuenta de las grandes posibilidades que tenía este pequeño trozo de código.

Al estar utilizando WordPress como backend primero miramos si había algún plugin hecho ya que nos facilitara las cosas. Encontramos uno, pero no conseguimos hacerlo funcionar, así que lo pusimos a pelo en la plantilla que estábamos creando. Nos basamos en la última versión que tiene uploadify ahora mismo estable, la 2.1.4, ya que la beta 3.0 carecía de documentación y no queríamos embarrarnos las manos con cosas no probadas.

Una vez bajado el archivo comprimido con todos los archivos necesarios, descomprimimos en la carpeta de nuestro tema. Con lo que quedaría todo dentro de una carpeta, en nuestro caso la llamamos uploadify.

Entonces hicimos la carga de los archivos .js necesarios y de la hoja de estilos .css. Nosotros siempre cargamos las hojas de estilo en la etiqueta <head>:

<link rel="stylesheet" type="text/css" media="all" href="<?php bloginfo( 'template_url' ); ?>/uploadify/uploadify.css" />

y la carga de los archivos javascript lo hacemos en el footer.php, justo antes del cierre del tag <body>:

<!-- Uploadify -->
<script type="text/javascript" src="<?php bloginfo( 'template_url' ); ?>/uploadify/swfobject.js"></script>
<script type="text/javascript" src="<?php bloginfo( 'template_url' ); ?>/uploadify/jquery.uploadify.v2.1.4.js"></script>

Utilizamos el código php bloginfo(‘template_url’) para poner la dirección absoluta donde se encuentran los archivos.

Queríamos que cada cliente tuviera su propio directorio para subir archivos con lo que necesitábamos el nombre de usuario una vez logueado el cliente. Así que en la página donde queríamos el uploader pusimos este trozo de código:

<script type="text/javascript">
var files = new Array();
var user = '<?php echo $username; ?>';
var $cont = 0;
           jQuery(document).ready(function() {
             jQuery('#file_upload').uploadify({
               'uploader'  : '<?php bloginfo( 'template_url' ); ?>/uploadify/uploadify.swf',
               'script'    : '<?php bloginfo( 'template_url' ); ?>/uploadify/uploadify.php',
               'cancelImg' : '<?php bloginfo( 'template_url' ); ?>/uploadify/cancel.png',
               'folder'    : '<?php echo URI_UPLOADS.'/'.$username.'/'; ?>',
               'auto'      : false,
               'removeCompleted' : false,
               'simUploadLimit' : 3,
               'buttonText' : '<?php _e('SELECCIONAR','nysplm'); ?>',
               'multi' : true,
               'onError' : function (event,ID,fileObj,errorObj) {
                 alert(errorObj.type + ' Error: ' + errorObj.info);
               },
               'onComplete' : function (event, ID, fileObj, response, data) {
                        var json = {"name": fileObj['name'], "size": fileObj['size'], "type": fileObj['type']};
                        files[$cont] = json;
                        $cont++;
                },
               'onAllComplete' : function (event, data) {
                        //alert("Response: "+response);
                        send_confirmation(data);
                        $cont = 0;
                        files = [];
                 }
              });
           });

Donde le decimos a uploadify:

  • uploader: donde está el archivo .swf que contiene el código flash que nos permitirá subir los archivos
  • script: donde está el archivo .php que necesita uploadify para hacer la carga de los archivos
  • cancelImg: donde se encuentra la imagen que se muestra para cancelar la subida de los archivos
  • folder: el directorio donde queremos subir los archivos. En nuestro caso esto es dinámico, así el cliente subirá los archivos a su propio directorio.
  • auto: indica que la subida no será automática, sino que el usuario deberá, una vez cargados los archivos, presionar un enlace para comenzar la carga.
  • removeCompleted: indicamos que no quite de pantalla los archivos subidos.
  • simUploadLimit: establecemos a 3 ficheros el límite de subida simultánea.
  • buttonText: ya que este gran software está en inglés, utilizamos esta opción para cambiar el texto del botón de carga de archivos.
  • multi: indicamos que se pueden subir varios archivos simultáneamente.
  • onError: función que mostrará una alerta js si se produce algún error.
  • onComplete: función que se ejecutará cada vez que se suba correctamente uno de los ficheros
  • onAllComplete: función que se ejecutará cuando se hayan subido todos los ficheros.

Alguien se habrá dado cuenta del comentario que hay en el onAllComplete:

 alert("Response: "+response);

Esto sirve de mucha ayuda cuando estamos desarrollando. Puede ser que el archivo no se suba correctamente por falta de permisos. Esto para uploadify no es un error, ya que no es competencia suya, con lo que el error es devuelto a la función onAllComplete en lugar de lanzar un error la función onError. Por ello, si vemos que no se muestra ningún error pero el archivo no se sube al servidor correctamente, descomentar esta línea puede aclarar que está pasando.

Y por último, y no menos importante, habrá que poner el tag donde se cargará uploadify:

<input id="file_upload" name="file_upload" type="file" />
<a href="javascript:$('#file_upload').uploadifyUpload();"><?php _e('Subir archivos','nysplm'); ?></a>

donde ponemos el input con el identificador que cargará uploadify y un enlace para subir los archivos simultáneamente.

Y hasta aquí, esperamos haber sido de ayuda. Si alguien tiene alguna duda pues a comentar. Ayudaremos en lo que podamos.