/**
* Copyright (c) 2011-2014, OpenIoT
*
* This file is part of OpenIoT.
*
* OpenIoT is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* OpenIoT 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenIoT. If not, see <http://www.gnu.org/licenses/>.
*
* Contact: OpenIoT mailto: info@openiot.eu
* @author cl3m
* @author Ali Salehi
* @author Mehdi Riahi
*/
package org.openiot.gsn.vsensor;
import org.openiot.gsn.beans.DataTypes;
import org.openiot.gsn.beans.StreamElement;
import org.openiot.gsn.beans.VSensorConfig;
import org.openiot.gsn.utils.protocols.ProtocolManager;
import org.openiot.gsn.utils.protocols.EPuck.SerComProtocol;
import org.openiot.gsn.wrappers.AbstractWrapper;
import org.openiot.gsn.wrappers.general.SerialWrapper;
import java.io.Serializable;
import java.util.TreeMap;
import javax.naming.OperationNotSupportedException;
import org.apache.log4j.Logger;
/**
* Virtual sensor to support GPS coord given by NMEA specification over serial
* Only the $GPRMC values are required.
* (works as well on bluetooth GPS mapped to serial)
*/
public class GPSNMEAVS extends AbstractVirtualSensor {
private static final transient Logger logger = Logger.getLogger( GPSNMEAVS.class );
private TreeMap < String , String > params;
private ProtocolManager protocolManager;
private AbstractWrapper wrapper;
private VSensorConfig vsensor;
private static final String [ ] fieldNames = new String [ ] { "latitude" , "longitude" };
private static final Byte [ ] fieldTypes = new Byte [ ] { DataTypes.DOUBLE, DataTypes.DOUBLE};
private Serializable [ ] outputData = new Serializable [ fieldNames.length ];
public boolean initialize ( ) {
vsensor = getVirtualSensorConfiguration( );
params = vsensor.getMainClassInitialParams( );
wrapper = vsensor.getInputStream( "input1" ).getSource( "source1" ).getWrapper( );
protocolManager = new ProtocolManager( new SerComProtocol( ) , wrapper );
if ( logger.isDebugEnabled( ) ) logger.debug( "Created protocolManager" );
try {
wrapper.sendToWrapper( "h\n" ,null,null);
} catch ( OperationNotSupportedException e ) {
e.printStackTrace( );
}
// protocolManager.sendQuery( SerComProtocol.RESET , null );
if ( logger.isDebugEnabled( ) ) logger.debug( "Initialization complete." );
return true;
}
public void dataAvailable ( String inputStreamName , StreamElement data ) {
if ( logger.isDebugEnabled( ) ) logger.debug( "SERIAL RAW DATA :"+new String((byte[])data.getData(SerialWrapper.RAW_PACKET)));
//needed? ######
AbstractWrapper wrapper = vsensor.getInputStream( "input1" ).getSource( "source1" ).getWrapper( );
//raw data from serial
String s = new String( ( byte [ ] ) data.getData( SerialWrapper.RAW_PACKET ) );
String [ ] line = s.split( "\n" );
//iterate on every line
for ( int i = 0 ; i < line.length ; i++ ) {
String [ ] part = line[ i ].split( "," );
//Only the $GPRMC line are analyed for GPS coord
//Using $GPGGA might be better but wouldn't give any result when no sat are tracked
if ( part[ 0 ].equals( "$GPRMC" ) ) {
//converting latitude from DDMM.MMMM to decimal notation
Double d = Double.valueOf( part[ 3 ] );
Double lat = d / 100.0;
lat = Math.floor( lat );
lat += Double.valueOf( d % 100.0 ) / 60.0;
if ( part[ 4 ].equals( "S" ) )
lat = -lat; // south coord
else if ( !part[ 4 ].equals( "N" ) )
continue; // neither south or north: invalid format -> skip
//converting longitude
d = Double.valueOf( part[ 5 ] );
Double lon = Math.floor( d / 100.0 );
lon += Double.valueOf( d % 100.0 ) / 60.0;
if ( part[ 6 ].equals( "W" ) )
lon = -lon; // west coord
logger.debug( "latitude:" + lat + " longitude:" + lon );
//send back the data
outputData[ 0 ] = lat;
outputData[ 1 ] = lon;
StreamElement output = new StreamElement( fieldNames , fieldTypes , outputData , System.currentTimeMillis( ) );
dataProduced( output );
break;//one $GPRMC line is enough
}
}
}
public void dispose ( ) {
}
}