package org.fluxtream.connectors.zeo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.fluxtream.core.domain.AbstractFacet;
import org.fluxtream.core.domain.ApiKey;
import org.fluxtream.core.domain.ChannelMapping;
import org.fluxtream.core.services.impl.BodyTrackHelper;
import org.fluxtream.core.services.impl.FieldHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.joda.time.DateTimeZone;
import org.joda.time.DateTime;
/**
*
* @author Candide Kemmler (candide@fluxtream.com)
*/
@Component("zeoSleepGraph")
public class ZeoSleepGraphFieldHandler implements FieldHandler {
int timeIncrement = 300; // 5 minutes
@Autowired
BodyTrackHelper bodyTrackHelper;
@Override
public List<BodyTrackHelper.BodyTrackUploadResult> handleField (final ApiKey apiKey, AbstractFacet facet) {
ZeoSleepStatsFacet sleepStatsFacet = (ZeoSleepStatsFacet) facet;
if (sleepStatsFacet.sleepGraph==null)
return Arrays.asList();
int graphSize = sleepStatsFacet.sleepGraph.length();
// To be consistent with the Zeo web site, round the start time down to the previous
// 5-minute boundary to compute the graph start time to use.
DateTime startTimeJoda = new DateTime(facet.start,DateTimeZone.UTC);
int stMin = startTimeJoda.getMinuteOfHour();
// Compute number of minutes we need to subtract from startTime to get graph start time
int gtMinSub = stMin%5;
// For some reason it looks like if the sleep time is at an even 5-minute boundary
// they are starting the graph 5 minutes before that
if(gtMinSub == 0) {
gtMinSub = 5;
}
// Subtract seconds/milliseconds of startTime + gtMinSub minutes in milliseconds
// from start to get graph start time
long graphStartTime = facet.start - (startTimeJoda.getMillisOfSecond()+startTimeJoda.getSecondOfMinute()*1000+gtMinSub*60000);
List<List<Object>> data = new ArrayList<List<Object>>();
for (int i=0; i<graphSize; i++) {
addSleepGraphColumn(data, sleepStatsFacet.sleepGraph, graphStartTime/1000+i*timeIncrement, i);
}
// TODO: check the status code in the BodyTrackUploadResult
return Arrays.asList(bodyTrackHelper.uploadToBodyTrack(apiKey , "Zeo", Arrays.asList("Sleep_Graph"), data));
}
private void addSleepGraphColumn(final List<List<Object>> data, final String sleepGraph, final long time, final int i) {
List<Object> record = new ArrayList<Object>();
record.add(time);
record.add(5-Integer.valueOf(""+sleepGraph.charAt(i)));
data.add(record);
}
@Override
public void addToDeclaredChannelMappings(final ApiKey apiKey, final List<ChannelMapping> channelMappings) {
ChannelMapping.addToDeclaredMappings(apiKey, 1, apiKey.getConnector().getDeviceNickname(), "Sleep_Graph", channelMappings);
}
}