La Cara Oscura del Desarrollo de Software La Cara Oscura del Desarrollo de Software 2008-09-09T21:26:03Z WordPress http://www.lacaraoscura.com/feed/atom/ Aníbal Rojas <![CDATA[Estamos cansados de esto (de WordPress)]]> http://www.lacaraoscura.com/?p=483 2008-09-09T21:26:03Z 2008-09-09T21:17:30Z Ya no lo soportamos más, no, no del blog, aunque lo hemos tenido medio abandonado. El problema real radica en los constantes ataques de los que es víctima esta instalación de WordPress buscando explotar las múltiples vulnerabilidades de este CMS.
Al margen de la obvia posibilidad de que existan vulnerabilidades en cualquier software que mueve un sitio en internet, sencillamente mantenerse al día con todas las actualizaciones de seguridad WordPress es más básicamente imposible a pesar de tener un plugin que las hace en forma automática.
Estamos cerrando todos los comentarios, trackbacks y pingbacks en esta instalación, para arrancar con una nueva usando otra herramienta que en nuestra experiencia resulta ser muuuuucho más robusta, por diseño e implementación, aunque con menos periquitos.

]]>
0
Leonardo Caballero http://lcaballero.wordpress.com/ <![CDATA[Plone: un sistema ágil y potente para de gestión de contenido]]> http://www.lacaraoscura.com/?p=476 2008-08-29T14:41:08Z 2008-08-29T14:32:53Z
por Leonardo Caballero ultima modificación 6 de Agosto de 2008 - 17:16

Contribuciones: dukebody

Plone: un sistema ágil y potente para de gestión de contenido

Fácil de empezar

Baterías incluidas

Soporta Linux, Windows, Mac OS X, FreeBSD, Solaris. Los programas de instalación le permiten ponerlo en marcha en sólo unos minutos. No requiere procesos de configuración complejos.

Habla su idioma

Disponible en más de 35 idiomas, Plone fue diseñado desde el inicio para gestionar contenido multilingüe. Incluye chino, japonés, e incluso idiomas con escritura de derecha a izquierda, como el árabe o el hebreo, de forma fácil.

El niño más bueno de la clase

El equipo de Plone incluye expertos líderes en usabilidad que han hecho que trabajar con Plone sea fácil y productivo.

A todo el mundo le gusta Plone

“Plone fue el ganador del premio del laboratorio de eWeek. Este producto de código abierto es de una de las mejores soluciones para los portales e intranets de empresas”.
eWeek, Número Abril de 2006

Amigable al usuario

No estorba y le deja escribir

Plone incluye un potente editor gráfico de texto que permite dar formato al texto e insertar imágenes y enlaces. Si está acostumbrado a trabajar con programas de ofimática, se sentirá cómodo con él.

Buscador de texto completo al instante

Todo el contenido está disponible inmediatamente para realizar búsquedas, incluso documentos Word y ficheros PDF. El sistema de búsqueda en vivo (LiveSearch) muestra los resultados a medida que se teclea la palabra o frase. Pruébelo en la casilla de búsqueda en este sitio.

Escalado de imágenes automático

Al subir una imagen, automáticamente se redimensiona a varios tamaños, lista para utilizarla en sus contenidos. No es necesario Photoshop.

Obtenga la mejor apariencia

Es fácil cambiar el aspecto de Plone. Simplemente puede integrarse con su imagen actual, o le permite crear un nuevo estilo totalmente propio.

Potente

Potente motor de flujo de trabajos (workflow)

Haga que los procesos de su negocio formen parte del flujo de trabajo del documento — complementado por una gestión de la seguridad a prueba de errores.

Velocidad y escalabilidad

Plone cuenta de serie con capacidad de realizar clústers e integrarse inteligentemente con proxys de caché. inteligente de caché proxy.

Seguridad y flexibilidad

Un modelo de seguridad sofisticado, basado en roles, da seguridad a sus contenidos. La arquitectura sandbox de Plone asegura que, incluso si su sistema estuviera comprometido, los intrusos no tendrán acceso a su servidor o a su red.

Sindicación y agregación

Carpetas inteligentes y actualizaciones inteligentes. Plone produce automáticamente noticias RSS desde carpetas, resultados de búsqueda y más — la manera ideal de permanecer en la cima de la explosión de la información y personalizar la entrega de información.

Compatible con los estándares

Accesibilidad

Reúne o supera los estándares de accesibilidad de la Sección 508 del Gobierno de los Estados Unidos y WAI-AA de W3C para personas con alguna discapacidad motora o con dificultad de lectura. Todo el uso de Javascript tiene un modo alternativo que funciona en cualquier navegador.

Excelente visibilidad en los motores de búsqueda

XHTML válido 100% y CSS mantienen una buena relación con los motores de búsqueda y los navegadores. Los sitios Plone están constantemente bien clasificados en los resultados de búsqueda en Google.

Juega bien con otros

LDAP, SQL, SOAP, Web Services (WSDL) y WebDAV — Plone trabaja con todos ellos.

Autenticación basada en agregados

Fácil integración con LDAP, Active Directory y bases de datos SQL. Diga un nombre y seguro que Plone puede dialogar con él.

Asistencia

Asistencia mundial

Si usa la documentación online, listas de correo y chats — u otros servicios de los cientos de empresas de todo el mundo que dan soporte Plone — nunca estará solo.

Código abierto, estándares abiertos

Plone está disponible bajo la misma licencia de código abierto que Linux, y usa el lenguaje de programación Python y el servidor de aplicaciones Zope, ambos también de código abierto. Esto evita dependencia del vendedor, costes de licencias, y le da un futuro previsible — y la libertad de innovar.

Extensa documentación, en prensa y online

Actualmente, hay cinco libros sobre Plone publicados, que ha sido traducidos al alemán, japonés y algunos otros idiomas.

Innovador y extensible

Hay disponibles cientos de productos adicionales — foros, gestores de incidencias, blogs y herramientas de colaboración.

Maduro

Protegido y maduro

Plone existe desde hace más de cinco años. La organización sin ánimo de lucro Plone Foundation es la propietaria y protege la propiedad intelectual y las marcas. Plone también tiene respaldo legal de los expertos del Software Freedom Law Center.

En buena compañía

Organizaciones diversas como NASA, Oxfam, eBay, Trolltech, Nokia, Utah State University, la CIA y Novell utilizan Plone para la gestión de contenidos. Nos encantaría daros la bienvenida a la comunidad Plone.

Plone es su arma secreta

Tanto si se usa para la intranet de una empresa como para un sitio web de una comunidad, Plone cumple.

Fuente

Plone: un sistema ágil y potente para de gestión de contenido

Escrito con el Navegador Flock

Tags: , , , ,

]]>
0
Román González <![CDATA[cout ]]> http://www.lacaraoscura.com/?p=475 2008-07-21T16:15:08Z 2008-07-21T16:12:56Z Despues de culminada mi epoca de maratones de la ACM, mi equipo (Guayoyo) y yo empezamos a llenar el vacio de competencias participando en TopCoder.

La lógica de TopCoder es un poco distinta a la de los maratones de programación de la ACM, entre las diferencias encontramos que, existe un sistema diferente de evaluación de problemas (por puntajes y tiempo), e incluso de formato en el código fuente (Se definen reglas estrictas acerca de los nombres de las clases y métodos).

Para ingresar en TopCoder es necesario tener Java instalado en nuestra maquina, ya que funciona mediante Applets o Java Web Start (el cual recomiendo). A pesar de que el sistema (de ahora en adelante “la arena”) funcione muy bien, la parte de edición de código fuente no es la mas idonia para trabajar en competencias bajo presión.

Para solucionar este problema, los programadores de TopCoder ofrecieron la posibilidad de implementar Plugins que se adaptan a la arena y permiten mejorar los editores de texto (o incluso no usarlos del todo). A continuación explicaremos como instalar y configurar algunos Plugins para mejorar nuestra productividad a la hora de realizar competencias dentro de TopCoder.

  1. Obtener el archivo .jws que carga la arena en nuestro computador

    Para obtener la aplicación de la arena, debemos acceder a este link (Como indicamos anteriormente, se debe tener Java instalado para que este funcione).

    Descargar la arena

  2. Ingresar al sistema (o registrarse en caso de que no nos encontremos registrados)

    En el caso de que no se encuentre registrado en el sistema, siga las indicaciones de la aplicación para registrarse

  3. Descargar los Plugins que harán tu vida más fácil

    Entre los Plugins que puedo recomendar, se encuentran CodeProcessorv2.0, FileEdit y moj

  4. Configurar los plugins dentro de la arena

    Para instalar los Plugins dentro de la arena se deben seguir los siguientes pasos:

    • Acceder al menú de “Options” y luego la opción “Editor”

      Options then Editor

    • Al abrirse la ventana de editores, debe presionar click en el botón “Add”, esto abrira otra ventana donde deben ingresar el nombre del editor (CodeProcessor en nuestro caso), en el campo EntryPoint, debemos colocar “codeprocessor.EntryPoint”, y en el campo classpath, al presionar el botón “Browse” debe buscar todos los Plugins (archivos .jar) que descargo en el paso anterior

      Configuración del Editor

    • Una vez instalado el nuevo editor, presionamos click en el botón “Configure”, se abrirá una nueva ventana donde se debe especificar en el campo “Editor EntryPoint” el valor “fileedit.EntryPoint”, luego presionamos el botón “Add” y en la nueva fila creada asignamos el valor “moj.moj”. Lo que hacemos aquí, es usar CodeProcessor como un manejador de Plugins, que permite usar varios Plugins (en este caso FileEdit y moj) simultaneamente.

      CodeProcessorConfig

    • Para configurar los plugins de FileEdit y moj, se debe presionar a los botones “Configure”, ahi se tendrán diferentes opciones dependiendo de cada Plugin

      ConfiugreButtons

    • Para finalizar, ingrese a la configuración de FileEdit, y en la pestaña de “Code Template”, en la opción de C++, ingrese el siguiente contenido

      $BEGINCUT$
      
      /*
      $PROBLEMDESC$
      */
      
      $ENDCUT$
      
      #line $NEXTLINENUMBER$ "$FILENAME$"
      #include "string"
      #include "vector"
      #include "algorithm"
      #include "map"
      #include "iterator"
      #include "iostream"
      #include "sstream"
      #include "cstdio"
      #include "cmath"
      #include "cstdlib"
      #include "queue"
      #include "stack"
      
      using namespace std;
      
      class $CLASSNAME$ {
      
        public:
      
        $RC$ $METHODNAME$($METHODPARMS$) {
      
        }
      };
      
      $BEGINCUT$
      $TESTCODE$ 
      
      $DEFAULTMAIN$
      $ENDCUT$
      

      Configuracion FileEdit

  5. Ahora… a programar

    Una vez instalados y configurados los Plugins, al momento de abrir un problema dentro de la arena, verá que el editor de texto no se encuentra en el programa de la arena, mas bien se muestra un log de acciones. Lo que ocurre es que el contenido del problema es descargado, y con este se genera un archivo que contendrá el enunciado del problema, junto con una implementación que contiene el template establecido en la configuración del FileEdit (que cambiará dependiendo del problema) y un main que ejecuta las pruebas del problema.

    Coding Area

Pero espere… hay más

Si se encuentra en Mac OS X, puede usar este script que implementé (basado en rstakeout) que se encarga de compilar y ejecutar los archivos .cpp modificados, y luego mandar mensajes via Growl. En el momento que el programa cumpla con todas las pruebas exitosamente, saldrá un mensaje diciendo “Send It”. Para enviarlo, sólo debes presionar el botón “Compile” en la arena, y luego al botón “Submit” (Reflejados en la figura anterior).

notificación

La carita verde es una imagen que configuré manualmente, si quieren tener algo parecido por favor revisen el código fuente y establezcan el lugar donde se encuentra la imagen que quieren usar, las caritas se encuentrán aquí.

Espero que estos tips les ayuden a mejorar su rendimiento en TopCoder…

]]>
0
josevnz http://www.kodegeek.com <![CDATA[¡Java es Socialista!]]> http://www.lacaraoscura.com/2008/06/23/%c2%a1java-es-socialista/ 2008-06-24T00:27:55Z 2008-06-24T00:27:55Z O capitalista, o Marxista, o Comunista o arroz con mango.

Es lamentable que a una herramienta de desarrollo de software o a un lenguaje se le tilde de esto o de aquello, sólo por desconocimiento. Pero lo peor es que esto se convierta en un trabajo de investigación (sin mucha base).

Mi argumentos reflejan lo que siempre he pensado del fanatismo de los desarrolladores. ¿Y usted que opina?

]]>
1
admin <![CDATA[ata2.00. exception Emask 0×0 SAct 0×0 action 0×2 frozen al iniciar Ubuntu 8.04 (Hardy Heron) en una DELL Inspiron 530]]> http://www.lacaraoscura.com/2008/06/22/ata200-exception-emask-0x0-sact-0x0-action-0x2-frozen-al-iniciar-ubuntu-804-hardy-heron-en-una-dell-inspiron-530/ 2008-06-23T00:10:58Z 2008-06-23T00:10:58Z La lentitud y los múltiples crashes de las aplicacciones en la DELL Inspiron 530 que compré para la casa a finales del año pasado hicieron que mi esposa y mi hija prácticamente me suplicaran que montara Ubuntu en la nueva máquina. Nunca pensé que tener una computadora con Windows Vista instalado fuera tan buen mercadeo para Linux ;-)

Por supuesto estaba el problema de los drivers, el monitor por sí solo es un mundo, etc. Sin embargo después de muchos fines de semana sin tiempo para respaldar, reparticionar, instalar y configurar,  por fin me dediqué a instalar Ubuntu 8.04, Hardy Heron.

Sin embargo después de la instalación se me quedaba "pegada" booteando con el siguiente mensaje:

CODE:
  1. ata2.00: status: {DRDY}
  2. ata2: soft resetting link
  3. ata2.00: configured for UDMA/33
  4. ata2: EH Complete
  5. ata2.00. exception Emask 0x0 SAct 0x0 action 0x2 frozen

Después de mucho escarbar en internet, pude resolver el problema agregando el parámetro pci=nomsi para el arranque del kernel, no estuvo fácil así que mejor postearlo aquí para que A) No se me olvide, B) Más nadie tenga que dar tumbos en los foros de Ubuntu, el WIki de DELL para soporte a Linux y cualquier otro recurso desquiciado en internet.

De momento el equipo funciona perfectamente, y mi mayor preocupación es que Gnomad2 se dispara con unos picos duros de consumo de CPU al sincronizar el Creative Labs Zen de mi hija con su "PlaysForSure" de Microsoft ;-)

Y ahora, por fin la máquina se comporta como un Core 2 Duo de 2.33 GHz, con 2 GB de RAM y una NVIDIA GeForce de 256MB y se acabará la letanía de ¿Y esta no "ique" era más rápida?

]]>
0
admin <![CDATA[Nginx: 4to lugar en Netcraft cortesía de WordPress.com]]> http://www.lacaraoscura.com/2008/06/11/nginx-4to-lugar-en-netcraft-cortesia-de-wordpresscom/ 2008-06-11T18:37:24Z 2008-06-11T18:37:24Z La gente de Netcraft reporta que para el mes de Mayo el servidor web Nginx ocupa el quinto lugar en su ranking. Esto cortesía de la gente de WordPress.com que reemplazaron Litespeed por Nginx, y que casualmente ayer generaron 36 millones de pageviews dinámicos con picos de 15k requests/sec en un pico histórico para su operación.

]]>
0
josevnz http://www.kodegeek.com <![CDATA[Capturando temperatura utilizando Sentilla Perk (II)]]> http://www.lacaraoscura.com/2008/05/24/capturando-temperatura-utilizando-sentilla-perk-ii/ 2008-05-25T02:54:07Z 2008-05-25T02:54:07Z En un articulo anterior les mostraba lo fácil que era utilizar el sensor (mote) de Sentilla Perk para capturar temperatura; Les comentaba también que una de las cosas más molestas del kit era que el gateway (el servidor con el cual instalamos software en los sensores y capturamos datos desde la red) sólo corre bajo Windows XP (aunque los ingenieros ya están trabajando en mejoras como drivers para Linux ys OSX).

OK, ¡suficiente habladera de tonterias!. Una forma de remediar esto es agregar otro protocolo (como TCP/IP) encima al programa original que recolectaba las temperaturas de todos los sensores, es decir lo convertimos en un servidor.

Lo primero es decidir si queremos usar un protocolo existente o si queremos reinventar la rueda; Para este experimento decidí que usar un protocolo existente con algunas modificaciones era lo más sencillo (Daytime, RFC686):

  • El servidor escucha en el puerto 1973 (cualquiera sirve si está libre ;)).
  • El cliente envia un paquete (vacio o no) al puerto 1973 en la máquina en donde corre el servidor
  • El servidor recibe el paquete y lo descarta. Envia de vuelta uno nuevo con una lista temperatura de todos los sensores que ha escuchado hasta el momento
  • El servidor no envia más temperaturas

El protocolo es sencillo, es puro texto (con una cabecera el cual el cliente utiliza como validación):
HEADER SENSORID1 SENSORCOUNT1 TEMPERATURE1 UNITS1 SENSORID2 SENSORCOUNT2 TEMPERATURE2 UNITS2 ...

Siempre es bueno encapsular los paquetes de un protocolo en una clase, para hacer más fácil su manejo:

JAVA:
  1. package com.kodegeek.blog.pervasive.perk;
  2.  
  3. /**
  4. * Simple model for temperature readings
  5. * @author josevnz
  6. *
  7. */
  8. public final class SimpleMessage {
  9.    
  10.     /**
  11.      * Valid status codes for the message
  12.      * @author josevnz@kodegeek.com
  13.      */
  14.     public enum Units {
  15.         FAHRENHEIT("Fahrenheit"),
  16.         CELCIUS("Celcius"),
  17.         UNKNOWN("Unknown");
  18.        
  19.         private String desc;
  20.        
  21.         Units(String desc) {
  22.             this.desc = desc;
  23.         }
  24.        
  25.         public String getDescription() {
  26.             return desc;
  27.         }
  28.        
  29.         public static Units getCode(int code) {
  30.             for (Units codes : Units.values()) {
  31.                 if (codes.ordinal() == code)
  32.                     return codes;
  33.             }
  34.             throw new IllegalArgumentException(String.format("Unknown code: %d", code));
  35.         }
  36.        
  37.     }
  38.    
  39.     private long count;
  40.     private long moteId;
  41.     private double temperature;
  42.     private Units units;
  43.    
  44.     /**
  45.      * Default constructor. By default is UNKLNOWN
  46.      */
  47.     public SimpleMessage() {
  48.         this(0, 0, 0.0, Units.UNKNOWN);
  49.     }
  50.    
  51.     /**
  52.      * Parametric constructor
  53.      * @param count Message count
  54.      * @param moteId sensor id
  55.      * @param temperature Temperature
  56.      * @param isRequest Is a request or a response
  57.      */
  58.     public SimpleMessage(long count, long moteId, double temperature, Units code) {
  59.         setCount(count);
  60.         setMoteId(moteId);
  61.         setTemperature(temperature);
  62.         setUnits(code);
  63.     }
  64.    
  65.     /**
  66.      * Get the message cou
  67.      * @return the count
  68.      */
  69.     public final long getCount() {
  70.         return count;
  71.     }
  72.    
  73.     /**
  74.      * Set the message count
  75.      * @param count the count to set
  76.      */
  77.     public final void setCount(long count) {
  78.         this.count = count;
  79.     }
  80.    
  81.     /**
  82.      * Return the sensor id
  83.      * @return the moteId
  84.      */
  85.     public final long getMoteId() {
  86.         return moteId;
  87.     }
  88.    
  89.     /**
  90.      * Set the sensor id
  91.      * @param moteId the moteId to set
  92.      */
  93.     public final void setMoteId(long moteId) {
  94.         this.moteId = moteId;
  95.     }
  96.    
  97.     /**
  98.      * @return the temperature
  99.      */
  100.     public final double getTemperature() {
  101.         return temperature;
  102.     }
  103.    
  104.     /**
  105.      * Set the temperature
  106.      * @param temperature the temperature to set. No validation is made as it depends a lot on the units
  107.      */
  108.     public final void setTemperature(double temperature) {
  109.         this.temperature = temperature;
  110.     }
  111.    
  112.     /**
  113.      * Get the units
  114.      * @return The state code
  115.      */
  116.     public final Units getUnits() {
  117.         return units;
  118.     }
  119.    
  120.     /**
  121.      * Set the units
  122.      * @param code Valid code to pass
  123.      */
  124.     public final void setUnits(Units code) {
  125.         this.units = code;
  126.     }
  127. }

El siguiente paso es decidir como codificar y decodificar el mensaje que enviamos a traves de la red; En el mundo Java podemos usar RMI, Sockets + Serialization sin embargo me pareció mejor utilizar UDP, por lo pequeño de los mensajes además de que no requiero las características extras de TCP, y no serialización (hay que ser MUY cuidadoso cuando se implementa, no es sólo decir que la clase implenta la interfaz "Serializable"):

JAVA:
  1. /**
  2. *
  3. */
  4. package com.kodegeek.blog.pervasive.perk;
  5.  
  6. /**
  7. * Define the contract to encode / decode a temperature message.
  8. * Not using the Sentilla radio protocol.
  9. */
  10. import java.io.IOException;
  11. import java.io.UnsupportedEncodingException;
  12. import java.util.ArrayList;
  13.  
  14. /**
  15. * @author josevnz
  16. *
  17. */
  18. public interface TemperatureCoder {
  19.  
  20.     /**
  21.      * Decode message from wire
  22.      * @param buffer
  23.      * @return TempMessage decoded from the wire
  24.      */
  25.      ArrayList<SimpleMessage> fromWire(byte [] buffer) throws IOException;
  26.    
  27.     /**
  28.      * Encoded message
  29.      * @param e
  30.      * @return byte array with serialized message
  31.      * @throws UnsupportedEncodingException
  32.      */
  33.     byte [] toWire(ArrayList<SimpleMessage> messages) throws IOException;
  34.    
  35. }

Si, una interfaz la cual va a implementar el codificador especifico (código aquí). De esta manera, si cambiamos el protocolo (usamos Java + Serialization por ejemplo), nuestra aplicación sólo tiene que cambiar la declaración del codificador concreto y listo.

¿Que viene después? Ah, envenenar al cliente original que capturaba la temperatura; Ahora va a ser un servidor El cual:

  • Va a capturar constantemente nuevas temperaturas desde la inalámbrica de los sensores en una hebra separada
  • Va a enviar todas las temperaturas disponibles a quien se las pida

Si bien el código del servidor no es muy largo (haga click aqui para verlo completo) prefiero mostrarle sólo las piezas críticas:

JAVA:
  1. /**
  2. * Server that collects the temperature readings of
  3. * all the motes in the wireless network.
  4. * @author josevnz@kodegeek.com
  5. */
  6.  
  7. package com.kodegeek.blog.pervasive.perk;
  8.  
  9. ...
  10.  
  11. /**
  12. * Iterative Server that collects all the temperature readings coming from the Sentilla Perk on the networks
  13. * @author josevnz@kodegeek.com
  14. *
  15. */
  16. public final class TemperatureService implements Runnable {
  17.  
  18.     private TemperatureService() {};
  19.  
  20.     private static final Logger log = Logger.getLogger(TemperatureService.class.getName());
  21.    
  22.     static {
  23.         log.setLevel(Level.FINEST);
  24.     }
  25.     private static final int DEFAULT_PORT = 1973;
  26.     protected static final int BUFFER_SIZE = 65507; // 65535 bytes - IP Header(20) - UDP header (8)
  27.     private static final int MOTE_WAIT = MoteTemperatureReader.WAIT_TIME;
  28.     private static final Map <Long, TempMessage>sensorMap = new ConcurrentHashMap<Long, TempMessage>();
  29.  
  30.     /**
  31.      * Capture sensor temperatures firever on a separate thread
  32.      */
  33.     public void run() {
  34.  
  35.         // Connect to the Sentilla server
  36.         HostClient client = new HostClient();
  37.         try {
  38.             client.connect();
  39.             log.log(Level.INFO, String.format("Connected to sensor gateway at %s, capturing temperatures", client.getHost()));
  40.             while(true) {
  41.                 Receiver receiver = ReceiverDriver.create(TempMessage.class);
  42.                 receiver.setReceive().submit().block(MOTE_WAIT);
  43.                 if (receiver.isDone()) {
  44.                     TempMessage tmsg = receiver.getData();
  45.                     sensorMap.put(tmsg.moteId, tmsg); // Save every sensor update, replacing previous one
  46.                     log.log(Level.FINE, String.format("Got update from sensor id: %s", tmsg.moteId));
  47.                 }
  48.             }
  49.         } catch (IOException ioExp) {
  50.             log.log(Level.SEVERE, "Severe error, response will be dropped", ioExp);
  51.         } finally {
  52.             try {
  53.                 if (client != null)
  54.                     client.disconnect();
  55.             } catch (IOException ioExp) {
  56.                 log.log(Level.SEVERE, "Error while closing sensor connection", ioExp);
  57.             }
  58.         }
  59.     }
  60.  
  61.     /**
  62.      * Collect the statistics from all the motes
  63.      * @param args
  64.      */
  65.     public static void main(String[] args) throws Throwable {
  66. ...
  67.  
  68.         // Start capturing temperatures
  69.         Thread tempThread = new Thread(new TemperatureService());
  70.         tempThread.start();
  71.  
  72.         DatagramSocket socket;
  73.         TemperatureCoder coder = new TemperatureTextCoder();
  74.         socket = null;
  75.         try {
  76.             socket = new DatagramSocket(port);
  77.             byte [] buffer = new byte[BUFFER_SIZE];
  78.  
  79.             DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
  80.             ArrayList<SimpleMessage>messages = new ArrayList<SimpleMessage>();
  81.  
  82.             while(true) { // Wait forever for new clients            
  83.                 try {
  84.                     socket.receive(packet); // Get the packet and discard the contents
  85.                     log.info(String.format("Got a connection from: %s", packet.getAddress()));
  86.                     // Send every available tick to the client in one shot
  87.                     for (TempMessage tmsg : sensorMap.values()) {
  88.                         SimpleMessage message = new SimpleMessage();
  89.                         // Get the temperature for the sensor
  90.                         double temp = tmsg.temperature.doubleValue(CELSIUS);
  91.                         message.setCount(tmsg.count);
  92.                         message.setMoteId(tmsg.moteId);
  93.                         message.setTemperature(temp);
  94.                         message.setUnits(SimpleMessage.Units.CELCIUS);
  95. ...
  96.                         messages.add(message);
  97.  
  98.                     } // end for every sensor
  99.                    
  100.                     // Send the whole pack to the client
  101.                     buffer = coder.toWire(messages);
  102.                     packet.setData(buffer, 0, buffer.length);
  103.                     socket.send(packet);
  104.     ...

Si, el servidor no es muy robusto ni soporta un gran número de clientes a la vez (es iterativo), pero para jugar un rato está bien :)

Bueno, si aún no le ha dado un ataque leyendo todo este código lo invito a que vea el cliente (código completo aqui) . Muy sencillo (sólo imprime por pantalla las temperaturas) sin embargo tiene una caracteristica muy importante: No tiene ninguna dependencia con el código de Sentilla:

JAVA:
  1. package com.kodegeek.blog.pervasive.perk;
  2.  
  3. ...
  4.  
  5. /**
  6. * Simple client that will get all the temperature readings from a TemperatureServer on the network.
  7. * @author josevnz@kodegeek.com
  8. *
  9. */
  10. public final class TemperatureClient {
  11.    
  12. ...
  13.    
  14.     /**
  15.      * @param args host (args[0]), port number (arg[1])
  16.      * @throws Throwable On any fatal error
  17.      */
  18.     public static void main(String[] args) throws Throwable {
  19. ...
  20.    
  21.         log.log(Level.INFO, "Starting TemperatureClient");
  22.        
  23.         TemperatureCoder coder = new TemperatureTextCoder();
  24.        
  25.         DatagramSocket socket = new DatagramSocket();
  26.         try {
  27.             InetAddress address = InetAddress.getByName(host);
  28.             socket.connect(address, port);
  29.             log.info(String.format("Contacting server on: %s:%s", address.getHostName(), port));
  30.            
  31.             // Send empty packet
  32.             byte [] buffer = new byte[TemperatureService.BUFFER_SIZE];
  33.             DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
  34.             int attempt = 1;
  35.             while(true) {
  36.                 try {
  37.                 socket.setSoTimeout(SOCKET_TIMEOUT);
  38.                 socket.send(packet); // Send empty packet
  39.                 socket.receive(packet); // Get the temperature reading
  40.                 buffer = new byte [packet.getLength()];
  41.                 System.arraycopy(packet.getData(), packet.getOffset(), buffer, 0, packet.getLength());
  42.  
  43.                 for (SimpleMessage messg: coder.fromWire(buffer)) {
  44.                     log.log(Level.INFO, String.format(
  45.                             "Mote ID: %d, Count: %d, Temperature: %.5f C\n",
  46.                             messg.getMoteId(),
  47.                             messg.getCount(),
  48.                             messg.getTemperature()));
  49.                 }
  50.                 packet.setLength(TemperatureService.BUFFER_SIZE);
  51.                 socket.setSoTimeout(0);
  52.                 Thread.sleep(SLEEP_TIME);
  53.     ... 
  54.                 }
  55.             }
  56.         } catch (IOException ioexp) {
  57.             log.log(Level.SEVERE, "There was a problem", ioexp);
  58.         } finally {
  59.             socket.close();
  60.         }
  61.     }
  62. }

Bueno, ahora lo que queda es ponerse a jugar conectándole otros sensores e incluso volviendo más inteligentes a los sensores.

¿Y ustedes que piensan? Intercambio de ideas y código van de la mano :)

]]>
6
josevnz http://www.kodegeek.com <![CDATA[Capturando temperatura utilizando Sentilla Perk]]> http://www.lacaraoscura.com/2008/05/18/capturando-temperatura-utilizando-sentilla-perk/ 2008-05-18T16:25:11Z 2008-05-18T16:25:11Z Sentilla Perk capturando datos en mi sala

Al fin tuve algo de tiempo para jugar con Sentilla Perk. Comencé escribiendo un hola mundo, el cual consiste en capturar temperatura con cada sensor para luego recolectar los resultados en mi laptop la cual corre el "gateway" que habla con los sensores:

JAVA:
  1. /**
  2.      * Get the temperature reading
  3.      * @throws InterruptedException
  4.      */
  5.  
  6.     public static void motemain() throws InterruptedException {
  7.  
  8.         Leds leds = LedsDriver.create();
  9.  
  10.         long id = Mac64Address.getLocalAddress().longValue();
  11.  
  12.        
  13.  
  14.         Sensor <Temperature>tempSensor = SensorDriver.create("temp", Temperature.class);
  15.  
  16.         Sender sender = SenderDriver.create("local");
  17.  
  18.         short count = 0;
  19.  
  20.         TempMessage datamsg = new TempMessage();
  21.  
  22.         datamsg.moteId = id;
  23.  
  24.         while(true) {
  25.  
  26.             count++;
  27.  
  28.             leds.toggle(count); // Play with the leds
  29.  
  30.  
  31.  
  32.             datamsg.count = count;
  33.  
  34.             datamsg.temperature = tempSensor.read(); // Read the temperature
  35.  
  36.             sender.send(datamsg);
  37.  
  38.            
  39.  
  40.             Thread.sleep(WAIT_TIME);
  41.  
  42.         }
  43.  
  44.     }

Es interesante programar usando Java para el dispositivo; El API es bien simple y por supuesto con limitaciones dado lo pequeño del entorno.

Todo en Java, y el mecanismo de comunicación completamente encapsulado, solamente hay que implementar la interfaz "Serializable".

Si quieren ver vídeos y más código entonces sigue el enlace.

]]>
2
josevnz http://www.kodegeek.com <![CDATA[Resumen de JavaOne 2008 y Java University]]> http://www.lacaraoscura.com/2008/05/11/resumen-de-javaone-2008-y-java-university/ 2008-05-11T21:50:04Z 2008-05-11T21:50:04Z JavaOne registration
El proceso de registro en JavaOne

Hola a todos,

Para no redundar en lo mismo, les dejo el enlace a mis impresiones sobre JavaOne del 2008. La experiencia fué realmente interesante.

]]>
0
josevnz http://www.kodegeek.com <![CDATA[Este Lunes 5 de Mayo arranca JavaOne en San Francisco]]> http://www.lacaraoscura.com/2008/05/02/este-lunes-5-de-mayo-arranca-javaone-en-san-francisco/ 2008-05-02T22:04:03Z 2008-05-02T22:04:03Z Este Lunes 5 de Mayo arranca JavaOne. Se esperan varias "sorpresas" entre ellas:

  • Nuevo progresos con JavaFX y el nuevo plugin del JDK para los browser
  • OpenJDK

Yo voy a estar el Lunes en el Java University, metiendome un puñal en JavaFX y Swing. Si el tiempo lo permite colocaré algunas de mis impresiones sobre la conferencia.

¡Lo cierto es que ando más emocionado que muchacho comiendo moco! :)

]]>
0