/**
*
* Copyright (c) 2009-2016 Freedomotic team http://freedomotic.com
*
* This file is part of Freedomotic
*
* This Program 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 2, or (at your option) any later version.
*
* This Program 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
* Freedomotic; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/
package com.freedomotic.plugins.devices.simulation;
import com.freedomotic.api.EventTemplate;
import com.freedomotic.api.Protocol;
import com.freedomotic.environment.ZoneLogic;
import com.freedomotic.exceptions.PluginStartupException;
import com.freedomotic.exceptions.UnableToExecuteException;
import com.freedomotic.model.geometry.FreedomPoint;
import com.freedomotic.plugins.devices.simulation.fromfile.WorkerThread;
import com.freedomotic.reactions.Command;
import com.freedomotic.settings.Info;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Enrico Nicoletti
*/
public class TrackingReadFile extends Protocol {
private static final Logger LOG = LoggerFactory.getLogger(TrackingReadFile.class.getName());
private final String DATA_TYPE = configuration.getStringProperty("data-type", "rooms");
private final int ITERATIONS = configuration.getIntProperty("iterations", 1);
private ArrayList<WorkerThread> workers = null;
/**
* Simulates a motes WSN. Positions are read from a text file.
*
*/
public TrackingReadFile() {
super("Tracking Simulator (Read file)", "/simulation/tracking-simulator-read-file.xml");
setDescription("Simulates a motes WSN. Positions are read from a text file");
}
@Override
public void onStart() throws PluginStartupException {
try {
workers = new ArrayList<>();
File dir = new File(Info.PATHS.PATH_DEVICES_FOLDER + "/simulation/data/motes");
String[] extensions = new String[]{"mote"};
LOG.info("Getting all \".mote\" files in \"{}\"", dir.getCanonicalPath());
List<File> motes = (List<File>) FileUtils.listFiles(dir, extensions, true);
if (!motes.isEmpty()) {
for (File file : motes) {
switch (DATA_TYPE) {
case "coordinates":
readMoteFileCoordinates(file);
break;
case "rooms":
readMoteFileRooms(file);
break;
default:
throw new PluginStartupException("<data-type> property wrong in manifest file");
}
}
for (WorkerThread workerThread : workers) {
workerThread.start();
}
} else {
throw new PluginStartupException("No \".mote\" files found.");
}
} catch (IOException ex) {
throw new PluginStartupException("Error during file \".motes\" loading." + ex.getMessage(), ex);
}
}
/**
* Reads coordinates from file.
*
* @param f file of coordinates
*/
private void readMoteFileCoordinates(File f) {
FileReader fr = null;
ArrayList<Coordinate> coord = new ArrayList<>();
String userId = FilenameUtils.removeExtension(f.getName());
try {
LOG.info("Reading coordinates from file \"{}\"", f.getAbsolutePath());
fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null) {
//tokenize string
StringTokenizer st = new StringTokenizer(line, ",");
LOG.info("Mote \"{}\" coordinate added \"{}\"", userId, line);
Coordinate c = new Coordinate();
c.setUserId(userId);
c.setX(new Integer(st.nextToken()));
c.setY(new Integer(st.nextToken()));
c.setTime(new Integer(st.nextToken()));
coord.add(c);
}
fr.close();
WorkerThread wt = new WorkerThread(this, coord, ITERATIONS);
workers.add(wt);
} catch (FileNotFoundException ex) {
LOG.error("Coordinates file not found for mote \"{}\"", userId);
} catch (IOException ex) {
LOG.error("IOException: ", ex);
} finally {
try {
if (fr != null) {
fr.close();
}
} catch (IOException ex) {
LOG.error("IOException: ", ex);
}
}
}
/**
* Reads room names from file.
*
* @param f file of room names
*/
private void readMoteFileRooms(File f) {
FileReader fr = null;
ArrayList<Coordinate> coord = new ArrayList<>();
String userId = FilenameUtils.removeExtension(f.getName());
try {
LOG.info("Reading coordinates from file \"{}\"", f.getAbsolutePath());
fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null) {
//tokenize string
StringTokenizer st = new StringTokenizer(line, ",");
String roomName = st.nextToken();
LOG.info("Mote \"{}\" coordinate added \"{}\"", userId, line);
ZoneLogic zone = getApi().environments().findAll().get(0).getZone(roomName);
if (zone != null) {
FreedomPoint roomCenterCoordinate = Utils.getPolygonCenter(zone.getPojo().getShape());
Coordinate c = new Coordinate();
c.setUserId(userId);
c.setX(roomCenterCoordinate.getX());
c.setY(roomCenterCoordinate.getY());
c.setTime(new Integer(st.nextToken()));
coord.add(c);
} else {
LOG.warn("Room \"{}\" not found.", roomName);
}
}
fr.close();
WorkerThread wt = new WorkerThread(this, coord, ITERATIONS);
workers.add(wt);
} catch (FileNotFoundException ex) {
LOG.error("Coordinates file not found for mote \"{}\"", userId);
} catch (IOException ex) {
LOG.error("IOException: ", ex);
} finally {
try {
if (fr != null) {
fr.close();
}
} catch (IOException ex) {
LOG.error("IOException: ", ex);
}
}
}
/**
* Gets the plugin logger.
*
* @return the logger
*/
public Logger getLog() {
return LOG;
}
@Override
protected void onRun() {
//do nothing
}
@Override
protected void onCommand(Command c) throws IOException, UnableToExecuteException {
//do nothing
}
@Override
protected boolean canExecute(Command c) {
//do nothing
return true;
}
@Override
protected void onEvent(EventTemplate event) {
//do nothing
}
}