Ahora que tengo mi servidor Mac mini ocioso creo que es hora de poner a trabajar ese equipo. Por ahora me estoy bajando las actualizaciones para OSX y poniéndole las pilas a los sensores
Estoy escribiendo una pequeña aplicación para Sentilla Labs. Comencé primero escribiendo una pequeña aplicación para calibrar el sensor (algo que no habia resuelto muy bien hace tiempo atrás). Lo cierto es que primero usted debe averiguar la temperatura del sitio del cual piensa sacar las medidas, usando quizas el termostato de su casa y luego corre esto desde Sentilla Works (el ide de Eclipse):
1package com.kodegeek.app.aguayfuego; 2 3import static javax.measure.unit.SI.CELSIUS; 4 5import javax.measure.quantity.Temperature; 6 7import com.sentilla.system.Leds; 8import com.sentilla.system.LedsDriver; 9import com.sentilla.system.PropertyDriver;10import com.sentilla.system.Sensor;11import com.sentilla.system.SensorDriver;1213/**14 * Calibrate the sensor using a known value15 * @author josevnz@kodegeek.com - http://kodegeek.com16 */17publicfinalclassSensorCalibration{1819/**20 * Persist the calibration temperature tobe used by all the applications21 * @throws InterruptedException22 */23publicstaticvoidmotemain()throwsInterruptedException{24Sensor<Temperature>tempSensor=SensorDriver.create("temp", Temperature.class);25Ledsleds=LedsDriver.create();26floatcalibratedTemp=25.0f;//Put here your known temperature27leds.toggle(1);28doubledelta=calibratedTemp-tempSensor.read().doubleValue(CELSIUS);29PropertyDriver.create("aguayfuego_temp_init", 8).writeDouble(delta);30leds.toggle(0);31}32}
Guardamos el valor en la lína 49. Una vez que usted corra este programa (solamente hace falta si sospecha que la temperatura de su cuarto ha cambiado mucho) entonces puede comenzar a capturar las temperaturas de nuevo. Fijense en el detalle de como se envia la temperatura, más el “delta” el cual contiene el ajuste:
1package com.kodegeek.app.aguayfuego; 2 3import static javax.measure.unit.SI.CELSIUS; 4import javax.measure.quantity.Temperature; 5import com.sentilla.net.Mac64Address; 6import com.sentilla.net.Sender; 7import com.sentilla.net.SenderDriver; 8import com.sentilla.system.Leds; 9import com.sentilla.system.LedsDriver;10import com.sentilla.system.PropertyDriver;11import com.sentilla.system.Sensor;12import com.sentilla.system.SensorDriver;1314/**15 * Simple class to capture temperature usingSentilla JMote16 * @author josevnz@kodegeek.com - http://kodegeek.com17 */1819publicfinalclassTemperatureCapture{20publicstaticfinalintWAIT_TIME=1000;2122/**23 * Get the temperature reading24 * @throws InterruptedException25 */26publicstaticvoidmotemain()throwsInterruptedException{27Sensor<Temperature>tempSensor=28SensorDriver.create("temp", Temperature.class);29Ledsleds=LedsDriver.create();30longid=Mac64Address.getLocalAddress().longValue();31Sendersender=SenderDriver.create("local");32shortcount=0;33TempMessagedatamsg=newTempMessage();34datamsg.moteId=id;35leds.toggle(0);36doubledelta=PropertyDriver.open("aguayfuego_temp_init").readDouble();37while(true){38count++;39datamsg.count=count;40datamsg.tempCelcius=tempSensor.read().doubleValue(CELSIUS)+delta;41leds.toggle(1);// Show the user the sensor is alive42sender.send(datamsg);43Thread.sleep(WAIT_TIME);44}45}46}
La línea 36 lee el delta y la 40 lee la temperatura con la corrección. Después la transmitimos en la linea 42.
Finalmente el cliente que lee los valores de los sensores (Esta es una aplicación común y silvestre de Java):
1package com.kodegeek.app.aguayfuego; 2 3import java.io.IOException; 4import java.util.Map; 5import java.util.concurrent.ConcurrentHashMap; 6import java.util.logging.Level; 7import java.util.logging.Logger; 8import com.sentilla.host.client.HostClient; 9import com.sentilla.net.Receiver;10import com.sentilla.net.ReceiverDriver;1112/**13 * Simple command line client that collectsthe temperature readings of14 * all the motes in the wireless network.15 * @author josevnz@kodegeek.com - http://kodegeek.com16 */17publicfinalclassTemperatureClient{1819privateTemperatureClient(){};2021privatestaticfinalLoggerlog=Logger.getLogger(TemperatureClient.class.getName());2223static{24log.setLevel(Level.INFO);25}2627privatestaticfinalintMOTE_WAIT=3000;2829/**30 * Helper class that captures the temperaturecomming from the sensor31 * @author josevnz32 */33classTemperatureCaptureHelper{34publicfinalMap<Long, TempMessage>sensorMap;3536/**37 * Parametric constructor38 * @param sensorMap Map to store all the captured temperatures39 */40publicTemperatureCaptureHelper(Map<Long, TempMessage>sensorMap){41this.sensorMap=sensorMap;42}4344publicvoidcapture(){4546// Connect to the Sentilla server47HostClientclient=newHostClient();48try{49client.connect();50log.log(Level.INFO,String.format("Connected to sensor gateway at %s,capturing temperatures",client.getHost()));51Receiverreceiver=ReceiverDriver.create(TempMessage.class);52while(true){53receiver.setReceive().submit().block(MOTE_WAIT);54if(receiver.isDone()){55TempMessagetmsg=receiver.getData();56sensorMap.put(tmsg.moteId, tmsg);57log.log(Level.INFO, String.format("Update from sensor id: %s, %.3f",tmsg.moteId, tmsg.tempCelcius));58}else{59log.log(Level.INFO, "No update");60}61}62}catch(IOExceptionioExp){63log.log(Level.SEVERE, "Severe error, response will be dropped", ioExp);64}finally{65try{66if(client!=null)67client.disconnect();68}catch(IOExceptionioExp){69log.log(Level.SEVERE,"Error while closing sensor connection", ioExp);70}71}72}73}7475/**76 * Collect the statistics from all the motes77 * @param args Unused78 */79publicstaticvoidmain(String[]args)throwsThrowable{80log.log(Level.INFO, "Starting TemperatureService");81finalTemperatureClientinstance=newTemperatureClient();82try{83finalMap<Long, TempMessage>temperatures=newConcurrentHashMap<Long, TempMessage>();84TemperatureCaptureHelperhelper=instance.newTemperatureCaptureHelper(temperatures);85helper.capture();86}catch(Throwablethrowbl){87log.log(Level.SEVERE, "Fatal error, no recover possible", throwbl);88throwthrowbl;89}90}91}
Una vez resuelto esto puedo comenzar con la nueva aplicación. El código no está disponible en CVS, en algún momento colocaré todo para que se lo bajen. Mientras tanto les dejo esto para que se entretengan
¿Recuerdan como les prometí que iba a jugar con Sentilla Perk? Hoy comencé con una sencilla aplicación la cual mide la temperatura usando los dos sensores (llamados “Motes”) para luego transmitirla a la laptop la cual tiene instalado el “Gateway” que habla el protocolo CC420 en el puerto USB.
Después de leer los ejemplos, la guia de programador y el API me conseguí que es muy fácil recolectar datos con los sensores. El código que hace la captura es el siguiente (este código es instalado desde la máquina que corre el servidor Perk en todos los motes):
Sendersender=SenderDriver.create("local");shortcount=0;TempMessagedatamsg=newTempMessage();datamsg.moteId=id;while(true){count++;leds.toggle(count);// Play with the ledsdatamsg.count=count;datamsg.temperature=tempSensor.read();// Read the temperaturesender.send(datamsg);Thread.sleep(WAIT_TIME);}
Y en la Laptop en donde estoy corriendo el servidor me limito a capturar la información enviada por los sensores para mostrarla por pantalla (código):
Pienso hacer una interfaz para poder mostrar esta información en Internet, esten pendientes. Por ahora los dejo con un video en el que se ve como corre el cliente que recibe los datos de los sensores:
Comentarios recientes