All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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";
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy