/* Copyright (C) 2017 João Paulo Barraca This file is part of Gadgetbridge. Gadgetbridge is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gadgetbridge 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus; /* * @author João Paulo Barraca <jpbarraca@gmail.com> */ import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; public class HPlusDataRecordSleep extends HPlusDataRecord { /** * Time which the device determined to be the bed time in seconds */ public int bedTimeStart; /** * Time which the device determined to be the end of this sleep period in seconds */ public int bedTimeEnd; /** * Number of minutes in Deep Sleep */ public int deepSleepMinutes; /** * Number of minutes in Light Sleep * This is considered as Light Sleep */ public int lightSleepMinutes; /** * Number of minutes to start sleeping (??) * This is considered as Light Sleep */ public int enterSleepMinutes; /** * Number of minutes with Sleep Spindles (??) * This is considered as Light Sleep */ public int spindleMinutes; /** * Number of minutes in REM sleep * This is considered as Light Sleep */ public int remSleepMinutes; /** * Number of wake up minutes during the sleep period * This is not considered as a sleep activity */ public int wakeupMinutes; /** * Number of times the user woke up */ public int wakeupCount; public HPlusDataRecordSleep(byte[] data) { super(data, TYPE_SLEEP); int year = (data[2] & 0xFF) * 256 + (data[1] & 0xFF); int month = data[3] & 0xFF; int day = data[4] & 0xFF; if (year < 2000) //Attempt to recover from bug from device. year += 1900; if (year < 2000 || month > 12 || day <= 0 || day > 31) { throw new IllegalArgumentException("Invalid record date: " + year + "-" + month + "-" + day); } enterSleepMinutes = ((data[6] & 0xFF) * 256 + (data[5] & 0xFF)); spindleMinutes = ((data[8] & 0xFF) * 256 + (data[7] & 0xFF)); deepSleepMinutes = ((data[10] & 0xFF) * 256 + (data[9] & 0xFF)); remSleepMinutes = ((data[12] & 0xFF) * 256 + (data[11] & 0xFF)); wakeupMinutes = ((data[14] & 0xFF) * 256 + (data[13] & 0xFF)); wakeupCount = ((data[16] & 0xFF) * 256 + (data[15] & 0xFF)); int hour = data[17] & 0xFF; int minute = data[18] & 0xFF; Calendar sleepStart = GregorianCalendar.getInstance(); sleepStart.clear(); sleepStart.set(Calendar.YEAR, year); sleepStart.set(Calendar.MONTH, month - 1); sleepStart.set(Calendar.DAY_OF_MONTH, day); sleepStart.set(Calendar.HOUR_OF_DAY, hour); sleepStart.set(Calendar.MINUTE, minute); sleepStart.set(Calendar.SECOND, 0); sleepStart.set(Calendar.MILLISECOND, 0); bedTimeStart = (int) (sleepStart.getTimeInMillis() / 1000); bedTimeEnd = (enterSleepMinutes + spindleMinutes + deepSleepMinutes + remSleepMinutes + wakeupMinutes) * 60 + bedTimeStart; lightSleepMinutes = enterSleepMinutes + spindleMinutes + remSleepMinutes; timestamp = bedTimeStart; } public List getIntervals() { List intervals = new ArrayList<>(); int ts = bedTimeStart + lightSleepMinutes * 60; intervals.add(new RecordInterval(bedTimeStart, ts, ActivityKind.TYPE_LIGHT_SLEEP)); intervals.add(new RecordInterval(ts, bedTimeEnd, ActivityKind.TYPE_DEEP_SLEEP)); return intervals; } public String toString(){ Calendar s = GregorianCalendar.getInstance(); s.setTimeInMillis(bedTimeStart * 1000L); Calendar end = GregorianCalendar.getInstance(); end.setTimeInMillis(bedTimeEnd * 1000L); return String.format(Locale.US, "Sleep start: %s end: %s enter: %d spindles: %d rem: %d deep: %d wake: %d-%d", s.getTime(), end.getTime(), enterSleepMinutes, spindleMinutes, remSleepMinutes, deepSleepMinutes, wakeupMinutes, wakeupCount); } }