mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-02-22 23:41:10 +01:00
huami: implement repeated activity fetching
Currently, huami only attempts to fetch activities once. Since sports activity fetching creates an Operation twice per every fetch, we need to pass around fetchCount variable to keep track of how many fetches has occured. Tested on my Amazfit GTR 4. Signed-off-by: Oleg Vasilev <me@svin.in>
This commit is contained in:
parent
d6c8d6b56d
commit
007f070125
@ -390,7 +390,7 @@ public abstract class Huami2021Support extends HuamiSupport {
|
||||
new FetchActivityOperation(this).perform();
|
||||
break;
|
||||
case RecordedDataTypes.TYPE_GPS_TRACKS:
|
||||
new FetchSportsSummaryOperation(this).perform();
|
||||
new FetchSportsSummaryOperation(this, 1).perform();
|
||||
break;
|
||||
case RecordedDataTypes.TYPE_DEBUGLOGS:
|
||||
new HuamiFetchDebugLogsOperation(this).perform();
|
||||
|
@ -87,7 +87,7 @@ public class AmazfitBipSupport extends HuamiSupport {
|
||||
if (dataTypes == RecordedDataTypes.TYPE_ACTIVITY) {
|
||||
new FetchActivityOperation(this).perform();
|
||||
} else if (dataTypes == RecordedDataTypes.TYPE_GPS_TRACKS) {
|
||||
new FetchSportsSummaryOperation(this).perform();
|
||||
new FetchSportsSummaryOperation(this, 1).perform();
|
||||
} else if (dataTypes == RecordedDataTypes.TYPE_DEBUGLOGS) {
|
||||
new HuamiFetchDebugLogsOperation(this).perform();
|
||||
} else {
|
||||
|
@ -17,6 +17,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations;
|
||||
|
||||
import android.text.format.DateUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@ -29,6 +30,7 @@ import java.io.IOException;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
@ -64,12 +66,14 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
||||
FetchSportsDetailsOperation(@NonNull BaseActivitySummary summary,
|
||||
@NonNull AbstractHuamiActivityDetailsParser detailsParser,
|
||||
@NonNull HuamiSupport support,
|
||||
@NonNull String lastSyncTimeKey) {
|
||||
@NonNull String lastSyncTimeKey,
|
||||
int fetchCount) {
|
||||
super(support);
|
||||
setName("fetching sport details");
|
||||
this.summary = summary;
|
||||
this.detailsParser = detailsParser;
|
||||
this.lastSyncTimeKey = lastSyncTimeKey;
|
||||
this.fetchCount = fetchCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -83,15 +87,6 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
||||
@Override
|
||||
protected boolean handleActivityFetchFinish(boolean success) {
|
||||
LOG.info(getName() + " has finished round " + fetchCount);
|
||||
// GregorianCalendar lastSyncTimestamp = saveSamples();
|
||||
// if (lastSyncTimestamp != null && needsAnotherFetch(lastSyncTimestamp)) {
|
||||
// try {
|
||||
// startFetching();
|
||||
// return;
|
||||
// } catch (IOException ex) {
|
||||
// LOG.error("Error starting another round of fetching activity data", ex);
|
||||
// }
|
||||
// }
|
||||
|
||||
boolean parseSuccess = true;
|
||||
|
||||
@ -125,7 +120,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
||||
}
|
||||
final String rawBytesPath = saveRawBytes();
|
||||
|
||||
String fileName = FileUtils.makeValidFileName("gadgetbridge-"+trackType.toLowerCase()+"-" + DateTimeUtils.formatIso8601(summary.getStartTime()) + ".gpx");
|
||||
String fileName = FileUtils.makeValidFileName("gadgetbridge-" + trackType.toLowerCase() + "-" + DateTimeUtils.formatIso8601(summary.getStartTime()) + ".gpx");
|
||||
File targetFile = new File(FileUtils.getExternalFilesDir(), fileName);
|
||||
|
||||
try {
|
||||
@ -147,18 +142,47 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
||||
}
|
||||
}
|
||||
|
||||
final boolean superSuccess = super.handleActivityFetchFinish(success);
|
||||
|
||||
if (success && parseSuccess) {
|
||||
// Always increment the sync timestamp on success, even if we did not get data
|
||||
GregorianCalendar endTime = BLETypeConversions.createCalendar();
|
||||
endTime.setTime(summary.getEndTime());
|
||||
saveLastSyncTimestamp(endTime);
|
||||
|
||||
if (needsAnotherFetch(endTime)) {
|
||||
FetchSportsSummaryOperation nextOperation = new FetchSportsSummaryOperation(getSupport(), fetchCount);
|
||||
try {
|
||||
nextOperation.perform();
|
||||
} catch (IOException ex) {
|
||||
LOG.error("Error starting another round of fetching activity data", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final boolean superSuccess = super.handleActivityFetchFinish(success);
|
||||
|
||||
return superSuccess && parseSuccess;
|
||||
}
|
||||
|
||||
private boolean needsAnotherFetch(GregorianCalendar lastSyncTimestamp) {
|
||||
// We have 2 operations per fetch round: summary + details
|
||||
if (fetchCount > 10) {
|
||||
LOG.warn("Already have 5 fetch rounds, not doing another one.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DateUtils.isToday(lastSyncTimestamp.getTimeInMillis())) {
|
||||
LOG.info("Hopefully no further fetch needed, last synced timestamp is from today.");
|
||||
return false;
|
||||
}
|
||||
if (lastSyncTimestamp.getTimeInMillis() > System.currentTimeMillis()) {
|
||||
LOG.warn("Not doing another fetch since last synced timestamp is in the future: {}", DateTimeUtils.formatDateTime(lastSyncTimestamp.getTime()));
|
||||
return false;
|
||||
}
|
||||
LOG.info("Doing another fetch since last sync timestamp is still too old: {}", DateTimeUtils.formatDateTime(lastSyncTimestamp.getTime()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validChecksum(int crc32) {
|
||||
return crc32 == CheckSums.getCRC32(buffer.toByteArray());
|
||||
@ -196,7 +220,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((byte) (lastPacketCounter + 1) == value[0] ) {
|
||||
if ((byte) (lastPacketCounter + 1) == value[0]) {
|
||||
lastPacketCounter++;
|
||||
bufferActivityData(value);
|
||||
} else {
|
||||
@ -208,6 +232,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
||||
/**
|
||||
* Buffers the given activity summary data. If the total size is reached,
|
||||
* it is converted to an object and saved in the database.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
@Override
|
||||
|
@ -57,9 +57,10 @@ public class FetchSportsSummaryOperation extends AbstractFetchOperation {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FetchSportsSummaryOperation.class);
|
||||
|
||||
private ByteArrayOutputStream buffer = new ByteArrayOutputStream(140);
|
||||
public FetchSportsSummaryOperation(HuamiSupport support) {
|
||||
public FetchSportsSummaryOperation(HuamiSupport support, int fetchCount) {
|
||||
super(support);
|
||||
setName("fetching sport summaries");
|
||||
this.fetchCount = fetchCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -73,15 +74,6 @@ public class FetchSportsSummaryOperation extends AbstractFetchOperation {
|
||||
protected boolean handleActivityFetchFinish(boolean success) {
|
||||
LOG.info(getName() + " has finished round " + fetchCount);
|
||||
|
||||
// GregorianCalendar lastSyncTimestamp = saveSamples();
|
||||
// if (lastSyncTimestamp != null && needsAnotherFetch(lastSyncTimestamp)) {
|
||||
// try {
|
||||
// startFetching();
|
||||
// return;
|
||||
// } catch (IOException ex) {
|
||||
// LOG.error("Error starting another round of fetching activity data", ex);
|
||||
// }
|
||||
// }
|
||||
|
||||
BaseActivitySummary summary = null;
|
||||
final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(getDevice());
|
||||
@ -124,7 +116,7 @@ public class FetchSportsSummaryOperation extends AbstractFetchOperation {
|
||||
if (summary != null) {
|
||||
final AbstractHuamiActivityDetailsParser detailsParser = ((HuamiActivitySummaryParser) summaryParser).getDetailsParser(summary);
|
||||
|
||||
FetchSportsDetailsOperation nextOperation = new FetchSportsDetailsOperation(summary, detailsParser, getSupport(), getLastSyncTimeKey());
|
||||
FetchSportsDetailsOperation nextOperation = new FetchSportsDetailsOperation(summary, detailsParser, getSupport(), getLastSyncTimeKey(), fetchCount);
|
||||
try {
|
||||
nextOperation.perform();
|
||||
} catch (IOException ex) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user