ch.epfl.gsn.wrappers.ieee1451.MoteIdentifier Maven / Gradle / Ivy
The newest version!
/**
* Global Sensor Networks (GSN) Source Code
* Copyright (c) 2006-2016, Ecole Polytechnique Federale de Lausanne (EPFL)
*
* This file is part of GSN.
*
* GSN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GSN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GSN. If not, see .
*
* File: src/ch/epfl/gsn/wrappers/ieee1451/MoteIdentifier.java
*
* @author Ali Salehi
* @author Mehdi Riahi
*
*/
package ch.epfl.gsn.wrappers.ieee1451;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import net.tinyos1x.message.Message;
import net.tinyos1x.message.MessageListener;
import net.tinyos1x.message.MoteIF;
import org.slf4j.LoggerFactory;
import ch.epfl.gsn.beans.AddressBean;
import ch.epfl.gsn.beans.DataField;
import ch.epfl.gsn.beans.DataTypes;
import ch.epfl.gsn.beans.InputStream;
import ch.epfl.gsn.beans.StreamElement;
import ch.epfl.gsn.utils.ChangeListener;
import ch.epfl.gsn.utils.LazyTimedHashMap;
import ch.epfl.gsn.wrappers.AbstractWrapper;
import org.slf4j.Logger;
public class MoteIdentifier extends AbstractWrapper implements MessageListener , ChangeListener {
private ArrayList < String > micaTEDS = new ArrayList < String >( );
private LazyTimedHashMap lazyActiveMicas;
/**
* The pooling interval in Milliseconds. How often pool for the TEDS. Used by motes and cameras.
*/
private int pooling_interval ;
/**
* The TimeOut in milliseconds. When to remove the TEDS. Used by motes and cameras.
*/
private int TIMEOUT = 30 * 1000;
private TedsToVSResult tedsResult;
private final Logger logger = LoggerFactory.getLogger( MoteIdentifier.class );
private int threadCounter = 0;
private String host;
private int port;
private MoteIF mote;
private String status;
private TedsToVirtualSensor tedsToVirtualSensor;
private static final String ADD_ACTION = "added";
private static final String REMOVE_ACTION = "removed";
private static final String ID_OUTPUT_FIELD = "ID";
private static final String TEDS_OUTPUT_FIELD = "TEDS";
private static final String STATUS_OUTPUT_FIELD = "STATUS";
private static final String VSFILE_OUTPUT_FIELD = "VSFILE";
private static final String [ ] OUTPUT_FIELD_NAMES = new String [ ] { ID_OUTPUT_FIELD , TEDS_OUTPUT_FIELD , STATUS_OUTPUT_FIELD , VSFILE_OUTPUT_FIELD };
private static final Byte [ ] OUTPUT_FIELD_TYPES = new Byte [ ] { DataTypes.VARCHAR , DataTypes.VARCHAR , DataTypes.VARCHAR , DataTypes.VARCHAR };
private boolean isConsumed = true;
private File templateFolder;
public boolean initialize ( ) {
// mica related
micaTEDS.add( 0 , "MicaONE.xml" );
micaTEDS.add( 1 , "MicaTWO.xml" );
micaTEDS.add( 2 , "MicaTHREE.xml" );
AddressBean addressBean = getActiveAddressBean( );
if ( addressBean.getPredicateValue( "TIMEOUT" ) != null ) {
TIMEOUT = Integer.parseInt( ( String ) addressBean.getPredicateValue( "TIMEOUT" ) );
}
/*
* pooling interval is five times less than the timeout value.
*/
pooling_interval = TIMEOUT/5;
host =addressBean.getPredicateValue( "host" );
if (host == null ){
logger.warn( "The MoteIdentifier couldn't initialize. The >host< parameter is missing from the set of the wrapper configuration parameters." );
return false;
}
port = addressBean.getPredicateValueAsInt("port", 9001);
// ------INITIALIZING THE TEMPLATE DIRECTORY ---------
String templateDirPath = addressBean.getPredicateValue( "templates-directory" );
if ( templateDirPath == null ) {
logger.warn( "The MoteIdentifier couldn't initialize. The >templates-directory< parameter is missing from the set of the wrapper configuration parameters." );
return false;
}
String templateFile = addressBean.getPredicateValue( "template-file" );
if ( templateFile == null ) {
logger.warn( "The MoteIdentifier couldn't initialize. The >template-file< parameter is missing from the set of the wrapper configuration parameters." );
return false;
}
templateFolder = new File( templateDirPath );
if ( !templateFolder.exists( ) || !templateFolder.isDirectory( ) || !templateFolder.canRead( ) ) {
logger.warn( "The MoteIdentifier couldn't initialize. Can't read >" + templateFolder.getAbsolutePath( ) + "<." );
return false;
}
File templateF = new File( templateFolder.getAbsolutePath( ) + "/" + templateFile + ".st" );
if ( !templateF.exists( ) || !templateF.isFile( ) || !templateF.canRead( ) ) {
logger.warn( "The MoteIdentifier couldn't initialize. Can't read >" + templateF.getAbsolutePath( ) + "<." );
return false;
}
tedsToVirtualSensor = new TedsToVirtualSensor( templateDirPath , templateFile );
// ------INITIALIZING THE TEMPLATE DIRECTORY ---------DONE
//
lazyActiveMicas = new LazyTimedHashMap( TIMEOUT );
lazyActiveMicas.addChangeListener( this );
// Serial Forwarder Related
logger.debug( "The MoteIdentifier connects to the Serial Forwarder interface at *" + host + ":" + port + "*" );
logger.info("Initializing the serial forwarder connection to: "+host+":"+port);
mote = new MoteIF( host , port );
mote.registerListener( new TedsMessage( ) , this );
outputStructure = new DataField [ ] { new DataField( ID_OUTPUT_FIELD , "varchar(20)" , "Id of the detected transducer" ) , new DataField( TEDS_OUTPUT_FIELD , "VARCHAR(8000)" , "TEDS-data" ) ,
new DataField( STATUS_OUTPUT_FIELD , "VARCHAR(20)" , "status:added or removed" ) , new DataField( VSFILE_OUTPUT_FIELD , "VARCHAR(40)" , "Virtual Sensor Filename" ) };
return true;
}
/**
* 1. GSN Data Containing SensorReadings 2. TEDS ID Packet sent by the mote
* containing TEDS_ID. its simple.. In this file.. we don't care about the
* GSNMessages..... all we care about is TEDSMessages.. Once we get the
* TEDSMessages.... We create corrsponding VS xmls..
*
* @param to Receiver ID
* @param m The actual message Received by us.
*/
public synchronized void messageReceived ( int to , Message m ) {
if ( isConsumed == false ) {
logger.info( "A Message is dropped because buffer is full." );
return;
}
if ( m instanceof TedsMessage ) {
if ( ( ( TedsMessage ) m ).dataLength( ) == 1 ) {
logger.debug( "TedsMessage Received."+ m.toString() );
int tedsID = ( ( TedsMessage ) m ).get_TEDS_ID( );
if ( lazyActiveMicas.get( tedsID ) != null ) {
logger.debug( "The sensor is alive and the virtual sensor file exists." );
} else {
status = ADD_ACTION;
isConsumed = false;
generateStreamElement( TedsReader.readTedsFromXMLFile( new File( templateFolder.getAbsolutePath( ) + "/" + micaTEDS.get( tedsID ) ) ) , status );
logger.info( "TEDS received and virtual sensor is generated with ID " + tedsID );
}
lazyActiveMicas.put( tedsID , Integer.toString( tedsID ) );
}
} else {
logger.warn( "DROPED : UNKOWN MESSAGE RECEVED" );
}
}
private void generateStreamElement ( TEDS teds , String status ) {
try {
Thread.sleep( 3000 );
} catch ( InterruptedException e ) {
e.printStackTrace( );
}
try {
if ( status == ADD_ACTION ) tedsResult = tedsToVirtualSensor.GenerateVS( teds );
if ( status == REMOVE_ACTION ) tedsResult = tedsToVirtualSensor.getTedsToVSResult( teds );
StreamElement streamElement = new StreamElement( OUTPUT_FIELD_NAMES , OUTPUT_FIELD_TYPES ,
new Serializable [ ] { tedsResult.tedsID , tedsResult.tedsHtmlString , status , tedsResult.fileName } , System.currentTimeMillis( ) );
postStreamElement( streamElement );
isConsumed = true;
} catch ( RuntimeException e1 ) {
logger.warn( "*TEDS ERROR" + e1.getMessage( ) , e1 );
}
}
private static transient DataField [ ] outputStructure;
public DataField [ ] getOutputFormat ( ) {
return outputStructure;
}
public void dispose ( ) {
threadCounter--;
}
public void run ( ) {
try {
Thread.sleep( InputStream.INITIAL_DELAY_5000MSC * 2 );
} catch ( InterruptedException e ) {
e.printStackTrace( );
}
mote.start( );
while ( isActive( ) ) {
try {
Thread.sleep( pooling_interval );
} catch ( InterruptedException e ) {
logger.error( e.getMessage( ) , e );
}
if ( listeners.isEmpty( ) ) continue;
TedsRequest tedsReq = new TedsRequest( );
tedsReq.set_Teds_Request( ( short ) 1 );
try {
mote.send( MoteIF.TOS_BCAST_ADDR , tedsReq );
} catch ( IOException e1 ) {
e1.printStackTrace( );
}
lazyActiveMicas.update( );
}
}
public void changeHappended ( String changeType , Object changedKey , Object changeValue ) {
if ( changeType == LazyTimedHashMap.ITEM_REMOVED ) {
status = REMOVE_ACTION;
generateStreamElement( TedsReader.readTedsFromXMLFile( new File( templateFolder.getAbsolutePath( ) + "/" + micaTEDS.get( ( Integer ) changedKey ) ) ) , status );
boolean success = ( new File( TedsToVirtualSensor.TARGET_VS_DIR + tedsResult.fileName ) ).delete( );
}
}
public String getWrapperName ( ) {
return "IEEE1451 IEEE 1451 mica mote";
}
}