mirror of
https://github.com/jwoglom/tconnectsync.git
synced 2026-08-26 02:34:14 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c35f850b9 | ||
|
|
a7383b0796 | ||
|
|
4f52927d2f | ||
|
|
5b938c010d | ||
|
|
3e50c7018d | ||
|
|
32f3639eb0 | ||
|
|
9a7cb1bdfd | ||
|
|
ead7ab883b | ||
|
|
ff395ffa3e | ||
|
|
8f2ad586fd | ||
|
|
828cccaf10 | ||
|
|
ae26102df2 | ||
|
|
152c263fe0 | ||
|
|
38c933a257 | ||
|
|
d507e47e7a | ||
|
|
8c2f41c2d5 | ||
|
|
018c6d2228 | ||
|
|
32ba49dc8a | ||
|
|
a5cbc5d612 | ||
|
|
ef515021cc | ||
|
|
4af54bf7cb |
@@ -10,6 +10,56 @@ on:
|
||||
branches: [ master, develop ]
|
||||
|
||||
jobs:
|
||||
build_old_python_versions:
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install flake8 pytest pipenv
|
||||
pipenv install --system
|
||||
pipenv install pyopenssl==22.1.0
|
||||
- name: Run pipenv check
|
||||
run: |
|
||||
# DDoS attacks in wheel and setuptools packages, not relevant
|
||||
# root certificate store, not relevant
|
||||
pipenv check \
|
||||
--ignore 51499 \
|
||||
--ignore 52495 \
|
||||
--ignore 52365 \
|
||||
--ignore 59956 \
|
||||
--ignore 58755 \
|
||||
--ignore 67895 \
|
||||
--ignore 61893 \
|
||||
--ignore 61601 \
|
||||
--ignore 62044 \
|
||||
--ignore 67599 \
|
||||
--ignore 72083 \
|
||||
--ignore 71064 \
|
||||
--ignore 71608 \
|
||||
--ignore 72236
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
||||
- name: Run tconnectsync --help
|
||||
run: |
|
||||
tconnectsync --help
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
pytest
|
||||
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
@@ -18,57 +68,60 @@ jobs:
|
||||
python-version: ['3.8', '3.9', '3.10', '3.11']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install flake8 pytest pipenv
|
||||
pipenv install --system
|
||||
- name: Run pipenv check
|
||||
run: |
|
||||
# DDoS attacks in wheel and setuptools packages, not relevant
|
||||
# root certificate store, not relevant
|
||||
pipenv check \
|
||||
--ignore 51499 \
|
||||
--ignore 52495 \
|
||||
--ignore 52365 \
|
||||
--ignore 59956 \
|
||||
--ignore 58755 \
|
||||
--ignore 67895 \
|
||||
--ignore 61893 \
|
||||
--ignore 61601 \
|
||||
--ignore 62044 \
|
||||
--ignore 67599 \
|
||||
--ignore 72083 \
|
||||
--ignore 71064 \
|
||||
--ignore 71608 \
|
||||
--ignore 72236
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
pytest
|
||||
- name: Check codecov configuration
|
||||
run: |
|
||||
curl -X POST --data-binary @.codecov.yml https://codecov.io/validate
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install flake8 pytest pipenv
|
||||
pipenv install --system
|
||||
- name: Run pipenv check
|
||||
run: |
|
||||
# DDoS attacks in wheel and setuptools packages, not relevant
|
||||
# root certificate store, not relevant
|
||||
pipenv check \
|
||||
--ignore 51499 \
|
||||
--ignore 52495 \
|
||||
--ignore 52365 \
|
||||
--ignore 59956 \
|
||||
--ignore 58755 \
|
||||
--ignore 67895 \
|
||||
--ignore 61893 \
|
||||
--ignore 61601 \
|
||||
--ignore 62044 \
|
||||
--ignore 67599 \
|
||||
--ignore 72083 \
|
||||
--ignore 71064 \
|
||||
--ignore 71608 \
|
||||
--ignore 72236
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
||||
- name: Run tconnectsync --help
|
||||
run: |
|
||||
tconnectsync --help
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
pytest
|
||||
- name: Check codecov configuration
|
||||
run: |
|
||||
curl -X POST --data-binary @.codecov.yml https://codecov.io/validate
|
||||
|
||||
if [[ "$(curl -s -o /dev/null -w "%{http_code}" -X POST --data-binary @.codecov.yml https://codecov.io/validate)" != "200" ]]; then
|
||||
echo Error parsing codecov file
|
||||
exit 1
|
||||
fi
|
||||
- name: Generate Coverage Report
|
||||
run: |
|
||||
pip install coverage
|
||||
coverage run -m unittest
|
||||
- name: Upload Coverage to Codecov
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
fail_ci_if_error: false
|
||||
if [[ "$(curl -s -o /dev/null -w "%{http_code}" -X POST --data-binary @.codecov.yml https://codecov.io/validate)" != "200" ]]; then
|
||||
echo Error parsing codecov file
|
||||
exit 1
|
||||
fi
|
||||
- name: Generate Coverage Report
|
||||
run: |
|
||||
pip install coverage
|
||||
coverage run -m unittest
|
||||
- name: Upload Coverage to Codecov
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
fail_ci_if_error: false
|
||||
|
||||
@@ -17,10 +17,11 @@ pysocks = "*"
|
||||
urllib3 = "==1.26.6"
|
||||
requests = {extras = ["socks"], version = "==2.31.0"}
|
||||
requests-oidc = "*"
|
||||
pyjwt = "*"
|
||||
PyJWT = "==2.8.0"
|
||||
cryptography = "*"
|
||||
dataclasses-json = "*"
|
||||
cffi = ">=1.15.1"
|
||||
typing-extensions = "*"
|
||||
|
||||
[scripts]
|
||||
tconnectsync = "python3 main.py"
|
||||
|
||||
Generated
+6
-5
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "74ba9aa4c7c93f3533b986f868b63bea54995dbd8d37bde4745bc9023de66dc7"
|
||||
"sha256": "1d28c5104c37e390b88704d1453eec15e5c6df241ca85f82a88973f8aee2d1d1"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@@ -471,12 +471,12 @@
|
||||
},
|
||||
"pyjwt": {
|
||||
"hashes": [
|
||||
"sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850",
|
||||
"sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"
|
||||
"sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de",
|
||||
"sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==2.9.0"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.8.0"
|
||||
},
|
||||
"pypng": {
|
||||
"hashes": [
|
||||
@@ -590,6 +590,7 @@
|
||||
"sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d",
|
||||
"sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==4.12.2"
|
||||
},
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[metadata]
|
||||
name = tconnectsync
|
||||
version = 2.0.2
|
||||
version = 2.0.8
|
||||
author = James Woglom
|
||||
author_email = j@wogloms.net
|
||||
description = Syncs Tandem t:connect pump data to Nightscout for the t:slim X2
|
||||
description = Syncs Tandem Source (formerly t:connect) insulin pump data to Nightscout for the t:slim X2
|
||||
long_description = file: README.md
|
||||
long_description_content_type = text/markdown
|
||||
url = https://github.com/jwoglom/tconnectsync
|
||||
@@ -25,6 +25,16 @@ install_requires =
|
||||
arrow
|
||||
lxml
|
||||
python-dotenv
|
||||
requests-mock
|
||||
pysocks
|
||||
urllib3
|
||||
requests
|
||||
requests-oidc
|
||||
PyJWT
|
||||
cryptography
|
||||
dataclasses-json
|
||||
cffi
|
||||
typing-extensions
|
||||
|
||||
[options.packages.find]
|
||||
where = .
|
||||
|
||||
@@ -4,6 +4,12 @@ import arrow
|
||||
import argparse
|
||||
import logging
|
||||
import pkg_resources
|
||||
import typing
|
||||
|
||||
# Required for cryptography lib in python 3.7
|
||||
if sys.version_info < (3, 8):
|
||||
import typing_extensions
|
||||
typing.Protocol = typing_extensions.Protocol
|
||||
|
||||
from .api import TConnectApi
|
||||
from .process import process_time_range
|
||||
@@ -114,6 +120,8 @@ def main(*args, **kwargs):
|
||||
sys.exit(u.process(tconnect, nightscout, time_start, time_end, args.pretend, features=args.features))
|
||||
else:
|
||||
tconnectDevice = TandemSourceChooseDevice(secret, tconnect).choose()
|
||||
added = TandemSourceProcessTimeRange(tconnect, nightscout, tconnectDevice, pretend=args.pretend, features=args.features).process(time_start, time_end)
|
||||
sys.exit(added)
|
||||
added, last_event_id = TandemSourceProcessTimeRange(tconnect, nightscout, tconnectDevice, pretend=args.pretend, features=args.features).process(time_start, time_end)
|
||||
|
||||
# return exit code 0 if processed events
|
||||
sys.exit(0 if added>0 else 1)
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import struct
|
||||
import arrow
|
||||
|
||||
from ..secret import TIMEZONE_NAME
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
EVENT_LEN = 26
|
||||
@@ -29,7 +31,11 @@ class RawEvent:
|
||||
seqNum = seqNum,
|
||||
raw = raw
|
||||
)
|
||||
|
||||
|
||||
@property
|
||||
def timestamp(self):
|
||||
return arrow.get(TANDEM_EPOCH + self.timestampRaw)
|
||||
# Event timestamps do not have TZ data attached to them when parsed,
|
||||
# but represent the user's time zone setting. So we keep the time
|
||||
# referenced on them, but force the timezone to what the user
|
||||
# requests via the TZ secret.
|
||||
return arrow.get(TANDEM_EPOCH + self.timestampRaw, tzinfo=TIMEZONE_NAME)
|
||||
|
||||
@@ -18,6 +18,7 @@ class TandemSourceAutoupdate:
|
||||
self.last_max_date_with_events = None
|
||||
self.last_event_time = 0
|
||||
self.last_attempt_time = 0
|
||||
self.last_event_index = None
|
||||
self.time_diffs_between_attempts = []
|
||||
self.time_diffs_between_updates = []
|
||||
|
||||
@@ -41,15 +42,17 @@ class TandemSourceAutoupdate:
|
||||
|
||||
tconnectDevice = ChooseDevice(self.secret, tconnect).choose()
|
||||
|
||||
cur_max_date_with_events = arrow.get(tconnectDevice['maxDateWithEvents'])
|
||||
if not self.last_max_date_with_events or cur_max_date_with_events > self.cur_max_date_with_events:
|
||||
event_id = None
|
||||
cur_max_date_with_events = arrow.get(tconnectDevice['maxDateWithEvents']).float_timestamp
|
||||
if not self.last_max_date_with_events or cur_max_date_with_events > self.last_max_date_with_events:
|
||||
logger.info('New reported tandemsource data. (cur_max_date: %s last_max_date: %s)' % (cur_max_date_with_events, self.last_max_date_with_events))
|
||||
|
||||
if pretend:
|
||||
logger.info('Would update now if not in pretend mode')
|
||||
else:
|
||||
added = ProcessTimeRange(tconnect, nightscout, tconnectDevice, pretend, features=features).process(time_start, time_end)
|
||||
added, event_id = ProcessTimeRange(tconnect, nightscout, tconnectDevice, pretend, features=features).process(time_start, time_end)
|
||||
logger.info('Added %d items from ProcessTimeRange' % added)
|
||||
self.last_successful_process_time_range = now
|
||||
|
||||
# Track the time it took to find a new event between runs,
|
||||
# but skip this calculation the first process cycle (since
|
||||
@@ -59,8 +62,10 @@ class TandemSourceAutoupdate:
|
||||
logger.debug('Updating tracking of time since last update: %s' % self.time_diffs_between_updates)
|
||||
|
||||
# Mark the last event index uploaded from the pump and timestamp
|
||||
if event_id:
|
||||
self.last_event_index = event_id
|
||||
self.last_event_time = now
|
||||
self.last_max_date_with_events = cur_max_date_with_events
|
||||
self.last_event_time = now
|
||||
self.last_attempt_time = now
|
||||
self.time_diffs_between_attempts = []
|
||||
else:
|
||||
|
||||
@@ -55,14 +55,18 @@ class ProcessTimeRange:
|
||||
|
||||
events_first_time = None
|
||||
events_last_time = None
|
||||
last_event_id = None # aka seqnum
|
||||
for_eventclass = collections.defaultdict(list)
|
||||
for event in events:
|
||||
if not events_first_time:
|
||||
events_first_time = event.eventTimestamp
|
||||
if not events_last_time:
|
||||
events_last_time = event.eventTimestamp
|
||||
if not last_event_id:
|
||||
last_event_id = event.eventId
|
||||
events_first_time = min(events_first_time, event.eventTimestamp)
|
||||
events_last_time = max(events_last_time, event.eventTimestamp)
|
||||
last_event_id = max(event.eventId, last_event_id)
|
||||
|
||||
clazz = EventClass.for_event(event)
|
||||
if clazz:
|
||||
@@ -91,6 +95,6 @@ class ProcessTimeRange:
|
||||
else:
|
||||
logger.info("Skipping %s, is not enabled from features %s" % (updater_class.__name__, self.features))
|
||||
|
||||
logger.info("Processed %d events" % processed_count)
|
||||
return processed_count
|
||||
logger.info("Processed %d events. Last event ID seen: %d" % (processed_count, last_event_id))
|
||||
return processed_count, last_event_id
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ class ProcessAlarm:
|
||||
|
||||
ns_entries = []
|
||||
for event in sorted(events, key=lambda x: x.eventTimestamp):
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) < last_upload_time:
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) <= last_upload_time:
|
||||
if self.pretend:
|
||||
logger.info("Skipping Alarm event before last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
logger.info("Skipping Alarm event not after last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
continue
|
||||
|
||||
ns_entries.append(self.alarm_to_nsentry(event))
|
||||
|
||||
@@ -36,13 +36,17 @@ class ProcessBasal:
|
||||
|
||||
with_duration = []
|
||||
for event in sorted(events, key=lambda x: x.eventTimestamp):
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) < last_upload_time:
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) <= last_upload_time:
|
||||
if self.pretend:
|
||||
logger.info("Skipping basal event before last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
logger.info("Skipping basal event not after last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
continue
|
||||
|
||||
with_duration.append([event.eventTimestamp, None, event])
|
||||
|
||||
if not with_duration:
|
||||
logger.info("No basal events found to process")
|
||||
return []
|
||||
|
||||
for i in range(len(with_duration)-1):
|
||||
with_duration[i][1] = with_duration[i+1][0] - with_duration[i][0]
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ class ProcessBasalResume:
|
||||
|
||||
ns_entries = []
|
||||
for event in sorted(events, key=lambda x: x.eventTimestamp):
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) < last_upload_time:
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) <= last_upload_time:
|
||||
if self.pretend:
|
||||
logger.info("Skipping BasalResume event before last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
logger.info("Skipping BasalResume event not after last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
continue
|
||||
|
||||
ns_entries.append(self.resume_to_nsentry(event))
|
||||
|
||||
@@ -35,9 +35,9 @@ class ProcessBasalSuspension:
|
||||
|
||||
ns_entries = []
|
||||
for event in sorted(events, key=lambda x: x.eventTimestamp):
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) < last_upload_time:
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) <= last_upload_time:
|
||||
if self.pretend:
|
||||
logger.info("Skipping basalsuspension event before last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
logger.info("Skipping basalsuspension event not after last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
continue
|
||||
|
||||
ns_entries.append(self.suspension_to_nsentry(event))
|
||||
|
||||
@@ -44,7 +44,7 @@ class ProcessBolus:
|
||||
bolusEventsForId[event.bolusid][type(event)] = event
|
||||
|
||||
if type(event) == eventtypes.LidBolusCompleted:
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) < last_upload_time:
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) <= last_upload_time:
|
||||
if self.pretend:
|
||||
logger.info("Skipping bolusCompletedEvent before last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
continue
|
||||
|
||||
@@ -37,9 +37,9 @@ class ProcessCartridge:
|
||||
cannulaFilledEvents = []
|
||||
tubingFilledEvents = []
|
||||
for event in sorted(events, key=lambda x: x.eventTimestamp):
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) < last_upload_time:
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) <= last_upload_time:
|
||||
if self.pretend:
|
||||
logger.info("Skipping %s before last upload time: %s (time range: %s - %s)" % (type(event), event, time_start, time_end))
|
||||
logger.info("Skipping %s not after last upload time: %s (time range: %s - %s)" % (type(event), event, time_start, time_end))
|
||||
continue
|
||||
|
||||
if type(event) == eventtypes.LidCartridgeFilled:
|
||||
|
||||
@@ -35,9 +35,9 @@ class ProcessCGMAlert:
|
||||
|
||||
alertEvents = []
|
||||
for event in sorted(events, key=lambda x: x.eventTimestamp):
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) < last_upload_time:
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) <= last_upload_time:
|
||||
if self.pretend:
|
||||
logger.info("Skipping %s before last upload time: %s (time range: %s - %s)" % (type(event), event, time_start, time_end))
|
||||
logger.info("Skipping %s not after last upload time: %s (time range: %s - %s)" % (type(event), event, time_start, time_end))
|
||||
continue
|
||||
|
||||
alertEvents.append(event)
|
||||
|
||||
@@ -38,9 +38,9 @@ class ProcessCGMReading:
|
||||
|
||||
readings = []
|
||||
for event in sorted(events, key=lambda x: self.timestamp_for(x)):
|
||||
if last_upload_time and self.timestamp_for(event) < last_upload_time:
|
||||
if last_upload_time and self.timestamp_for(event) <= last_upload_time:
|
||||
if self.pretend:
|
||||
logger.info("ProcessCGMReading: Skipping %s before last upload time: %s (time range: %s - %s)" % (type(event), event, time_start, time_end))
|
||||
logger.info("ProcessCGMReading: Skipping %s not after last upload time: %s (time range: %s - %s)" % (type(event), event, time_start, time_end))
|
||||
continue
|
||||
|
||||
readings.append(event)
|
||||
|
||||
@@ -48,9 +48,9 @@ class ProcessCGMStartJoinStop:
|
||||
|
||||
allEvents = []
|
||||
for event in sorted(events, key=lambda x: x.eventTimestamp):
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) < last_upload_time:
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) <= last_upload_time:
|
||||
if self.pretend:
|
||||
logger.info("ProcessCGMStartJoinStop: Skipping %s before last upload time: %s (time range: %s - %s)" % (type(event), event, time_start, time_end))
|
||||
logger.info("ProcessCGMStartJoinStop: Skipping %s not after last upload time: %s (time range: %s - %s)" % (type(event), event, time_start, time_end))
|
||||
continue
|
||||
|
||||
allEvents.append(event)
|
||||
|
||||
@@ -72,9 +72,9 @@ class ProcessUserMode:
|
||||
start_sleep = None
|
||||
start_exercise = None
|
||||
for event in sorted(events, key=lambda x: x.eventTimestamp):
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) < last_upload_time:
|
||||
if last_upload_time and arrow.get(event.eventTimestamp) <= last_upload_time:
|
||||
if self.pretend:
|
||||
logger.info("ProcessUserMode: Skipping usermode event before last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
logger.info("ProcessUserMode: Skipping usermode event not after last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
|
||||
continue
|
||||
|
||||
if self.is_start_sleep(event):
|
||||
|
||||
Reference in New Issue
Block a user