/**
* 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 <http://www.gnu.org/licenses/>.
*
* File: src/ch/epfl/gsn/vsensor/WebInteractiveVirtualSensor.java
*
* @author Ali Salehi
* @author Mehdi Riahi
*
*/
package ch.epfl.gsn.vsensor;
import java.awt.Color;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.TreeMap;
import javax.naming.OperationNotSupportedException;
import org.slf4j.LoggerFactory;
import ch.epfl.gsn.beans.DataTypes;
import ch.epfl.gsn.beans.StreamElement;
import ch.epfl.gsn.beans.VSensorConfig;
import ch.epfl.gsn.others.visualization.svg.SVGCircle;
import ch.epfl.gsn.others.visualization.svg.SVGEdge;
import ch.epfl.gsn.others.visualization.svg.SVGLayer;
import ch.epfl.gsn.others.visualization.svg.SVGPage;
import ch.epfl.gsn.others.visualization.svg.SVGUtils;
import ch.epfl.gsn.utils.LazyTimedHashMap;
import ch.epfl.gsn.utils.ParamParser;
import ch.epfl.gsn.vsensor.AbstractVirtualSensor;
import org.slf4j.Logger;
public class WebInteractiveVirtualSensor extends AbstractVirtualSensor {
private static final transient Logger logger = LoggerFactory.getLogger( WebInteractiveVirtualSensor.class );
/*
* This method is going to be called by the container when one of the input
* streams has a data to be delivered to this virtual sensor. After receiving
* the data, the virutal sensor can do the processing on it and this
* processing could possibly result in producing a new stream element in this
* virtual sensor in which case the virutal sensor will notify the container
* by simply adding itself to the list of the virtual sensors which have
* produced data. (calling <code>container.publishData(this)</code>. For
* more information please check the <code>AbstractVirtalSensor</code>
* @param inputStreamName is the name of the input stream as specified in the
* configuration file of the virtual sensor. @param inputDataFromInputStream
* is actually the real data which is produced by the input stream and should
* be delivered to the virtual sensor for possible processing.
*/
private LazyTimedHashMap lazyTimedHashMap;
private final String INPUT_STREAM_NAME = "DATA";
private final String OUTPUT_FIELD_NAME = "PLOT";
private int counter_pref = 0;
private VSensorConfig vsensor;
public boolean initialize ( ) {
TreeMap < String , String > params = getVirtualSensorConfiguration( ).getMainClassInitialParams( );
int memorySizeInSeconds = ParamParser.getInteger( params.get( "memory-size-in-seconds" ) , -1 );
if ( memorySizeInSeconds == -1 ) {
logger.error( "The parameter *memory-size-in-seconds* is missing from the virtual sensor processing class's initialization." );
logger.error( "Loading the virtual sensor failed" );
return false;
} else {
lazyTimedHashMap = new LazyTimedHashMap( memorySizeInSeconds * 1000 );
}
return true;
}
public void dataAvailable ( String inputStreamName , StreamElement streamElement ) {
if ( inputStreamName.equalsIgnoreCase( INPUT_STREAM_NAME ) ) {
int node_id = ( Integer ) streamElement.getData( "NODE_ID" );
int parent_id = ( Integer ) streamElement.getData( "PARENT_ID" );
float tempreature = 0f;
SVGCircle simpleNodeObject = new SVGCircle( new SimpleNodeObject( node_id , parent_id , SimpleNodeObject.REQUEST_TYPE_DATA , tempreature ) , Color.blue );
lazyTimedHashMap.put( node_id , simpleNodeObject );
}
ArrayList < SVGCircle > arrayList = lazyTimedHashMap.getValues( );
byte [ ] visualizedResults = visualaize( 400 , 400 , arrayList ).getBytes( );
StreamElement out = new StreamElement( new String [ ] { OUTPUT_FIELD_NAME } , new Byte[ ] { DataTypes.BINARY } , new Serializable [ ] { visualizedResults } , System.currentTimeMillis( ) );
dataProduced( out );
}
public boolean dataFromWeb ( String command, String[] paramNames, Serializable[] paramValues ) {
String streamSourceAliasName = "ss_bla";
try {
return vsensor.getInputStream( INPUT_STREAM_NAME ).getSource( streamSourceAliasName ).getWrapper().sendToWrapper( command , paramNames , paramValues );
} catch ( OperationNotSupportedException e ) {
logger.warn( new StringBuilder( ).append( "The virtual sensor : " ).append( vsensor.getName( ) ).append(
" want to send data to a stream source which doesn't support receiving data." ).toString( ) );
logger.warn( e.getMessage( ) , e );
return false;
}
}
public static String visualaize ( int width , int height , ArrayList < SVGCircle > nodes ) {
ArrayList < SVGEdge > edges = new ArrayList < SVGEdge >( );
SVGLayer edgesLayer = new SVGLayer( "Edges" , 0.8f );
SVGLayer nodesLayer = new SVGLayer( "Nodes" , 1f );
for ( SVGCircle node : nodes )
for ( SVGCircle parent : nodes )
if ( node != parent && ( ( SimpleNodeObject ) node.getObject( ) ).getParentID( ) == ( ( SimpleNodeObject ) parent.getObject( ) ).getNodeID( ) ) {
SVGEdge edge = new SVGEdge( node , parent , false );
edgesLayer.addElement( edge );
edges.add( edge );
edge.setWidth( 3 );
}
nodesLayer.addElements( nodes );
SVGPage svgPage = new SVGPage( width , height );
svgPage.addLayer( edgesLayer ).addLayer( nodesLayer );
SVGUtils.performLayout( nodes , edges , SVGUtils.TREE_HORIZ , svgPage.getWidth( ) , svgPage.getHeight( ) );
StringBuilder toReturn = new StringBuilder( );
svgPage.drawOn( toReturn );
return toReturn.toString( );
}
public void dispose ( ) {
}
}
class SimpleNodeObject {
private final int NOT_SPECIFIED = -1;
public static final int REQUEST_TYPE_DATA = 1;
int nodeID = NOT_SPECIFIED;
int parentID = NOT_SPECIFIED;
int requestType = NOT_SPECIFIED;
double tempreatureValue = NOT_SPECIFIED;
public SimpleNodeObject ( int nodeID , int parentID , int requestType , double tempreatureValue ) {
this.nodeID = nodeID;
this.parentID = parentID;
this.requestType = requestType;
this.tempreatureValue = tempreatureValue;
}
public int getNodeID ( ) {
return nodeID;
}
public int getParentID ( ) {
return parentID;
}
public int getRequestType ( ) {
return requestType;
}
public double getTempreatureValue ( ) {
return tempreatureValue;
}
}