Compare commits

...
33 Commits
Author SHA1 Message Date
James Woglom 9c35f850b9 v2.0.8 2024-10-02 00:54:29 -04:00
James Woglom a7383b0796 fix return code 2024-10-02 00:52:41 -04:00
James Woglom 4f52927d2f try to fix jwt import error 2024-10-02 00:45:39 -04:00
James Woglom 5b938c010d only conditionally import typing_extensions 2024-10-02 00:39:56 -04:00
James Woglom 3e50c7018d py3.7 force pyopenssl 2024-10-01 21:02:04 -04:00
James Woglom 32f3639eb0 py3.7 actions 2024-10-01 17:29:49 -04:00
James Woglom 9a7cb1bdfd no anchors 2024-10-01 17:27:01 -04:00
James Woglom ead7ab883b check old python versions 2024-10-01 17:25:26 -04:00
James Woglom ff395ffa3e test on py3.7 2024-10-01 17:17:55 -04:00
James Woglom 8f2ad586fd v2.0.7: fix py3.7 compat 2024-10-01 17:17:33 -04:00
James Woglom 828cccaf10 v2.0.6: update install_requires packages 2024-10-01 17:05:54 -04:00
James Woglom ae26102df2 v2.0.5 2024-10-01 17:01:40 -04:00
James Woglom 152c263fe0 Use pyjwt v2.8 to allow python3.7 support 2024-10-01 16:56:19 -04:00
James Woglom 38c933a257 v2.0.4 2024-10-01 16:50:19 -04:00
James Woglom d507e47e7a convert to float 2024-10-01 16:44:20 -04:00
James Woglom 8c2f41c2d5 skip processing no basal events 2024-10-01 16:30:18 -04:00
James Woglom 018c6d2228 dont repeat the last event on a process cycle 2024-10-01 16:29:23 -04:00
James Woglom 32ba49dc8a autoupdate bugfix 2024-10-01 16:24:43 -04:00
James Woglom a5cbc5d612 v2.0.3 2024-10-01 16:08:06 -04:00
James Woglom ef515021cc check changes for last seen event id 2024-10-01 16:07:48 -04:00
James Woglom 4af54bf7cb set tzinfo (fix #100) 2024-10-01 15:59:20 -04:00
James Woglom d9d1b8a8fb v2.0.2 2024-09-30 01:13:28 -04:00
James Woglom 29ed755356 3.8+ and add 3.11 2024-09-30 01:13:06 -04:00
James Woglom b862ea9d0d pin 2024-09-30 01:12:26 -04:00
James Woglom 2677fc86be pin arrow version for py3.7 compat 2024-09-30 01:09:25 -04:00
James Woglom 1ae40e3cdb python3.7 compat 2024-09-30 01:06:21 -04:00
James Woglom 90c63c8211 py3.7 compat 2024-09-30 00:58:22 -04:00
James Woglom 60c2e08dcf py3.7 compat 2024-09-30 00:53:14 -04:00
James Woglom d6f08c61b8 v2.0.1 2024-09-30 00:50:07 -04:00
James Woglom 784387dcb8 sensor start/stop/join eventtypes 2024-09-30 00:49:59 -04:00
James Woglom 84092e1de6 formatting fixes 2024-09-30 00:32:07 -04:00
James Woglom bb3094869d fix old tests (will be removed/updated) 2024-09-30 00:14:16 -04:00
James Woglom ec497d7d00 unit bugfixes 2024-09-30 00:09:38 -04:00
26 changed files with 478 additions and 275 deletions
+107 -54
View File
@@ -10,65 +10,118 @@ 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
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
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
+6 -4
View File
@@ -9,17 +9,19 @@ ptpython = "*"
[packages]
tconnectsync = {path = "."}
bs4 = "*"
arrow = "*"
arrow = "==1.2.3"
lxml = "*"
python-dotenv = "*"
python-dotenv = "==0.21.1"
requests-mock = "*"
pysocks = "*"
urllib3 = "==1.26.6"
requests = {extras = ["socks"], version = "*"}
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
+20 -26
View File
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "586b477d4c73da1d1034f852a536bf3c20a1a358406bfb5dfc1b1164f606441b"
"sha256": "1d28c5104c37e390b88704d1453eec15e5c6df241ca85f82a88973f8aee2d1d1"
},
"pipfile-spec": 6,
"requires": {},
@@ -16,12 +16,12 @@
"default": {
"arrow": {
"hashes": [
"sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80",
"sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"
"sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1",
"sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==1.3.0"
"markers": "python_version >= '3.6'",
"version": "==1.2.3"
},
"beautifulsoup4": {
"hashes": [
@@ -117,7 +117,8 @@
"sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87",
"sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"
],
"markers": "platform_python_implementation != 'PyPy'",
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==1.17.1"
},
"charset-normalizer": {
@@ -470,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": [
@@ -504,12 +505,12 @@
},
"python-dotenv": {
"hashes": [
"sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca",
"sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"
"sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49",
"sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==1.0.1"
"markers": "python_version >= '3.7'",
"version": "==0.21.1"
},
"qrcode": {
"hashes": [
@@ -524,11 +525,11 @@
"socks"
],
"hashes": [
"sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760",
"sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"
"sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
"sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
],
"markers": "python_version >= '3.8'",
"version": "==2.32.3"
"markers": "python_version >= '3.7'",
"version": "==2.31.0"
},
"requests-mock": {
"hashes": [
@@ -584,19 +585,12 @@
"markers": "python_version >= '3.6'",
"version": "==0.9.4"
},
"types-python-dateutil": {
"hashes": [
"sha256:27c8cc2d058ccb14946eebcaaa503088f4f6dbc4fb6093d3d456a49aef2753f6",
"sha256:9706c3b68284c25adffc47319ecc7947e5bb86b3773f843c73906fd598bc176e"
],
"markers": "python_version >= '3.8'",
"version": "==2.9.0.20240906"
},
"typing-extensions": {
"hashes": [
"sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d",
"sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==4.12.2"
},
+12 -2
View File
@@ -1,9 +1,9 @@
[metadata]
name = tconnectsync
version = 2.0.0
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 = .
+10 -2
View File
@@ -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)
+3 -3
View File
@@ -13,7 +13,7 @@ def parse_date(date):
def parse_ymd_date(date):
if type(date) == str:
return date
date = arrow.get(date)
return (date or datetime.datetime.now()).strftime('%Y-%m-%d')
def parsed_date_to_arrow(date):
@@ -122,11 +122,11 @@ def split_days_range(start_a, end_a, days: int = 5) -> List[Tuple[str, str]]:
if (cur - cur_s).days >= days-1:
ranges.append((cur_s, cur))
cur_s = cur + datetime.timedelta(days=1)
cur += datetime.timedelta(days=1)
if len(ranges) > 0 and (end - ranges[-1][-1]).days > 0:
ranges.append((cur_s, end))
return ranges
class ApiException(Exception):
+173 -83
View File
@@ -58,7 +58,8 @@ class LidBasalRateChange(BaseEvent):
@property
def changetype(self):
try: return self.ChangetypeBitmask(self.changetypeRaw)
try:
return self.ChangetypeBitmask(self.changetypeRaw)
except ValueError as e:
logger.error("Invalid changetypeRaw in ChangetypeBitmask for "+str(self))
logger.error(e)
@@ -235,7 +236,8 @@ class LidAlertActivated(BaseEvent):
@property
def alertid(self):
try: return self.AlertidEnum(self.alertidRaw)
try:
return self.AlertidEnum(self.alertidRaw)
except ValueError as e:
logger.error("Invalid alertidRaw in Alertid for "+str(self))
logger.error(e)
@@ -412,7 +414,8 @@ class LidAlarmActivated(BaseEvent):
@property
def alarmid(self):
try: return self.AlarmidEnum(self.alarmidRaw)
try:
return self.AlarmidEnum(self.alarmidRaw)
except ValueError as e:
logger.error("Invalid alarmidRaw in Alarmid for "+str(self))
logger.error(e)
@@ -506,7 +509,8 @@ class LidPumpingSuspended(BaseEvent):
@property
def suspendreason(self):
try: return self.SuspendreasonEnum(self.suspendreasonRaw)
try:
return self.SuspendreasonEnum(self.suspendreasonRaw)
except ValueError as e:
logger.error("Invalid suspendreasonRaw in Suspendreason for "+str(self))
logger.error(e)
@@ -662,7 +666,8 @@ class LidBgReadingTaken(BaseEvent):
@property
def selectediob(self):
try: return self.SelectediobEnum(self.selectediobRaw)
try:
return self.SelectediobEnum(self.selectediobRaw)
except ValueError as e:
logger.error("Invalid selectediobRaw in Selectediob for "+str(self))
logger.error(e)
@@ -679,7 +684,8 @@ class LidBgReadingTaken(BaseEvent):
@property
def bgentrytype(self):
try: return self.BgentrytypeEnum(self.bgentrytypeRaw)
try:
return self.BgentrytypeEnum(self.bgentrytypeRaw)
except ValueError as e:
logger.error("Invalid bgentrytypeRaw in Bgentrytype for "+str(self))
logger.error(e)
@@ -696,7 +702,8 @@ class LidBgReadingTaken(BaseEvent):
@property
def bgsourcetype(self):
try: return self.BgsourcetypeEnum(self.bgsourcetypeRaw)
try:
return self.BgsourcetypeEnum(self.bgsourcetypeRaw)
except ValueError as e:
logger.error("Invalid bgsourcetypeRaw in Bgsourcetype for "+str(self))
logger.error(e)
@@ -713,7 +720,8 @@ class LidBgReadingTaken(BaseEvent):
@property
def cgmcalibration(self):
try: return self.CgmcalibrationEnum(self.cgmcalibrationRaw)
try:
return self.CgmcalibrationEnum(self.cgmcalibrationRaw)
except ValueError as e:
logger.error("Invalid cgmcalibrationRaw in Cgmcalibration for "+str(self))
logger.error(e)
@@ -786,7 +794,8 @@ class LidBolusCompleted(BaseEvent):
@property
def completionstatus(self):
try: return self.CompletionstatusEnum(self.completionstatusRaw)
try:
return self.CompletionstatusEnum(self.completionstatusRaw)
except ValueError as e:
logger.error("Invalid completionstatusRaw in Completionstatus for "+str(self))
logger.error(e)
@@ -853,7 +862,8 @@ class LidBolexCompleted(BaseEvent):
@property
def completionstatus(self):
try: return self.CompletionstatusEnum(self.completionstatusRaw)
try:
return self.CompletionstatusEnum(self.completionstatusRaw)
except ValueError as e:
logger.error("Invalid completionstatusRaw in Completionstatus for "+str(self))
logger.error(e)
@@ -1028,7 +1038,8 @@ class LidAlertCleared(BaseEvent):
@property
def alertid(self):
try: return self.AlertidEnum(self.alertidRaw)
try:
return self.AlertidEnum(self.alertidRaw)
except ValueError as e:
logger.error("Invalid alertidRaw in Alertid for "+str(self))
logger.error(e)
@@ -1198,7 +1209,8 @@ class LidAlarmCleared(BaseEvent):
@property
def alarmid(self):
try: return self.AlarmidEnum(self.alarmidRaw)
try:
return self.AlarmidEnum(self.alarmidRaw)
except ValueError as e:
logger.error("Invalid alarmidRaw in Alarmid for "+str(self))
logger.error(e)
@@ -1319,7 +1331,8 @@ class LidBolusActivated(BaseEvent):
@property
def selectediob(self):
try: return self.SelectediobEnum(self.selectediobRaw)
try:
return self.SelectediobEnum(self.selectediobRaw)
except ValueError as e:
logger.error("Invalid selectediobRaw in Selectediob for "+str(self))
logger.error(e)
@@ -1372,7 +1385,8 @@ class LidBolexActivated(BaseEvent):
@property
def selectediob(self):
try: return self.SelectediobEnum(self.selectediobRaw)
try:
return self.SelectediobEnum(self.selectediobRaw)
except ValueError as e:
logger.error("Invalid selectediobRaw in Selectediob for "+str(self))
logger.error(e)
@@ -1458,7 +1472,8 @@ class LidCannulaFilled(BaseEvent):
@property
def completionstatus(self):
try: return self.CompletionstatusEnum(self.completionstatusRaw)
try:
return self.CompletionstatusEnum(self.completionstatusRaw)
except ValueError as e:
logger.error("Invalid completionstatusRaw in Completionstatus for "+str(self))
logger.error(e)
@@ -1510,7 +1525,8 @@ class LidTubingFilled(BaseEvent):
@property
def completionstatus(self):
try: return self.CompletionstatusEnum(self.completionstatusRaw)
try:
return self.CompletionstatusEnum(self.completionstatusRaw)
except ValueError as e:
logger.error("Invalid completionstatusRaw in Completionstatus for "+str(self))
logger.error(e)
@@ -1568,7 +1584,8 @@ class LidBolusRequestedMsg1(BaseEvent):
@property
def bolustype(self):
try: return self.BolustypeEnum(self.bolustypeRaw)
try:
return self.BolustypeEnum(self.bolustypeRaw)
except ValueError as e:
logger.error("Invalid bolustypeRaw in Bolustype for "+str(self))
logger.error(e)
@@ -1585,7 +1602,8 @@ class LidBolusRequestedMsg1(BaseEvent):
@property
def correctionbolusincluded(self):
try: return self.CorrectionbolusincludedEnum(self.correctionbolusincludedRaw)
try:
return self.CorrectionbolusincludedEnum(self.correctionbolusincludedRaw)
except ValueError as e:
logger.error("Invalid correctionbolusincludedRaw in Correctionbolusincluded for "+str(self))
logger.error(e)
@@ -1653,7 +1671,8 @@ class LidBolusRequestedMsg2(BaseEvent):
@property
def selectediob(self):
try: return self.SelectediobEnum(self.selectediobRaw)
try:
return self.SelectediobEnum(self.selectediobRaw)
except ValueError as e:
logger.error("Invalid selectediobRaw in Selectediob for "+str(self))
logger.error(e)
@@ -1682,7 +1701,8 @@ class LidBolusRequestedMsg2(BaseEvent):
@property
def options(self):
try: return self.OptionsEnum(self.optionsRaw)
try:
return self.OptionsEnum(self.optionsRaw)
except ValueError as e:
logger.error("Invalid optionsRaw in Options for "+str(self))
logger.error(e)
@@ -1699,7 +1719,8 @@ class LidBolusRequestedMsg2(BaseEvent):
@property
def useroverride(self):
try: return self.UseroverrideEnum(self.useroverrideRaw)
try:
return self.UseroverrideEnum(self.useroverrideRaw)
except ValueError as e:
logger.error("Invalid useroverrideRaw in Useroverride for "+str(self))
logger.error(e)
@@ -1716,7 +1737,8 @@ class LidBolusRequestedMsg2(BaseEvent):
@property
def declinedcorrection(self):
try: return self.DeclinedcorrectionEnum(self.declinedcorrectionRaw)
try:
return self.DeclinedcorrectionEnum(self.declinedcorrectionRaw)
except ValueError as e:
logger.error("Invalid declinedcorrectionRaw in Declinedcorrection for "+str(self))
logger.error(e)
@@ -1901,7 +1923,8 @@ class LidPlgsPeriodic(BaseEvent):
@property
def fmrstatus(self):
try: return self.FmrstatusEnum(self.fmrstatusRaw)
try:
return self.FmrstatusEnum(self.fmrstatusRaw)
except ValueError as e:
logger.error("Invalid fmrstatusRaw in Fmrstatus for "+str(self))
logger.error(e)
@@ -1918,7 +1941,8 @@ class LidPlgsPeriodic(BaseEvent):
@property
def pgvvalid(self):
try: return self.PgvvalidEnum(self.pgvvalidRaw)
try:
return self.PgvvalidEnum(self.pgvvalidRaw)
except ValueError as e:
logger.error("Invalid pgvvalidRaw in Pgvvalid for "+str(self))
logger.error(e)
@@ -1937,7 +1961,8 @@ class LidPlgsPeriodic(BaseEvent):
@property
def rulestate(self):
try: return self.RulestateBitmask(self.rulestateRaw)
try:
return self.RulestateBitmask(self.rulestateRaw)
except ValueError as e:
logger.error("Invalid rulestateRaw in RulestateBitmask for "+str(self))
logger.error(e)
@@ -1958,7 +1983,8 @@ class LidPlgsPeriodic(BaseEvent):
@property
def hominstate(self):
try: return self.HominstateEnum(self.hominstateRaw)
try:
return self.HominstateEnum(self.hominstateRaw)
except ValueError as e:
logger.error("Invalid hominstateRaw in Hominstate for "+str(self))
logger.error(e)
@@ -1996,7 +2022,8 @@ class LidPlgsPeriodic(BaseEvent):
@property
def status(self):
try: return self.StatusBitmask(self.statusRaw)
try:
return self.StatusBitmask(self.statusRaw)
except ValueError as e:
logger.error("Invalid statusRaw in StatusBitmask for "+str(self))
logger.error(e)
@@ -2053,7 +2080,8 @@ class LidCgmAlertActivated(BaseEvent):
"20": "CGM Transmitter Error",
"26": "CGM Temperature",
"27": "CGM Failed Connection",
"39": "CGM Transmitter Expired"
"39": "CGM Transmitter Expired",
"40": "Pump Bluetooth Error"
}
class DalertidEnum(Enum):
@@ -2064,10 +2092,12 @@ class LidCgmAlertActivated(BaseEvent):
CgmTemperature = 26
CgmFailedConnection = 27
CgmTransmitterExpired = 39
PumpBluetoothError = 40
@property
def dalertid(self):
try: return self.DalertidEnum(self.dalertidRaw)
try:
return self.DalertidEnum(self.dalertidRaw)
except ValueError as e:
logger.error("Invalid dalertidRaw in Dalertid for "+str(self))
logger.error(e)
@@ -2113,7 +2143,8 @@ class LidCgmAlertCleared(BaseEvent):
"20": "CGM Transmitter Error",
"26": "CGM Temperature",
"27": "CGM Failed Connection",
"39": "CGM Transmitter Expired"
"39": "CGM Transmitter Expired",
"40": "Pump Bluetooth Error"
}
class DalertidEnum(Enum):
@@ -2124,10 +2155,12 @@ class LidCgmAlertCleared(BaseEvent):
CgmTemperature = 26
CgmFailedConnection = 27
CgmTransmitterExpired = 39
PumpBluetoothError = 40
@property
def dalertid(self):
try: return self.DalertidEnum(self.dalertidRaw)
try:
return self.DalertidEnum(self.dalertidRaw)
except ValueError as e:
logger.error("Invalid dalertidRaw in Dalertid for "+str(self))
logger.error(e)
@@ -2214,7 +2247,8 @@ class LidUpdateStatus(BaseEvent):
@property
def updatesuccessful(self):
try: return self.UpdatesuccessfulEnum(self.updatesuccessfulRaw)
try:
return self.UpdatesuccessfulEnum(self.updatesuccessfulRaw)
except ValueError as e:
logger.error("Invalid updatesuccessfulRaw in Updatesuccessful for "+str(self))
logger.error(e)
@@ -2329,7 +2363,8 @@ class LidCgmJoinSessionGx(BaseEvent):
@property
def sessionjoinreason(self):
try: return self.SessionjoinreasonEnum(self.sessionjoinreasonRaw)
try:
return self.SessionjoinreasonEnum(self.sessionjoinreasonRaw)
except ValueError as e:
logger.error("Invalid sessionjoinreasonRaw in Sessionjoinreason for "+str(self))
logger.error(e)
@@ -2405,7 +2440,8 @@ class LidCgmStopSessionGx(BaseEvent):
@property
def sessionstopreason(self):
try: return self.SessionstopreasonEnum(self.sessionstopreasonRaw)
try:
return self.SessionstopreasonEnum(self.sessionstopreasonRaw)
except ValueError as e:
logger.error("Invalid sessionstopreasonRaw in Sessionstopreason for "+str(self))
logger.error(e)
@@ -2465,7 +2501,8 @@ class LidAaUserModeChange(BaseEvent):
@property
def exercisechoice(self):
try: return self.ExercisechoiceEnum(self.exercisechoiceRaw)
try:
return self.ExercisechoiceEnum(self.exercisechoiceRaw)
except ValueError as e:
logger.error("Invalid exercisechoiceRaw in Exercisechoice for "+str(self))
logger.error(e)
@@ -2486,7 +2523,8 @@ class LidAaUserModeChange(BaseEvent):
@property
def currentusermode(self):
try: return self.CurrentusermodeEnum(self.currentusermodeRaw)
try:
return self.CurrentusermodeEnum(self.currentusermodeRaw)
except ValueError as e:
logger.error("Invalid currentusermodeRaw in Currentusermode for "+str(self))
logger.error(e)
@@ -2507,7 +2545,8 @@ class LidAaUserModeChange(BaseEvent):
@property
def previoususermode(self):
try: return self.PrevioususermodeEnum(self.previoususermodeRaw)
try:
return self.PrevioususermodeEnum(self.previoususermodeRaw)
except ValueError as e:
logger.error("Invalid previoususermodeRaw in Previoususermode for "+str(self))
logger.error(e)
@@ -2536,7 +2575,8 @@ class LidAaUserModeChange(BaseEvent):
@property
def requestedaction(self):
try: return self.RequestedactionEnum(self.requestedactionRaw)
try:
return self.RequestedactionEnum(self.requestedactionRaw)
except ValueError as e:
logger.error("Invalid requestedactionRaw in Requestedaction for "+str(self))
logger.error(e)
@@ -2553,7 +2593,8 @@ class LidAaUserModeChange(BaseEvent):
@property
def sleepstartedbygui(self):
try: return self.SleepstartedbyguiEnum(self.sleepstartedbyguiRaw)
try:
return self.SleepstartedbyguiEnum(self.sleepstartedbyguiRaw)
except ValueError as e:
logger.error("Invalid sleepstartedbyguiRaw in Sleepstartedbygui for "+str(self))
logger.error(e)
@@ -2570,7 +2611,8 @@ class LidAaUserModeChange(BaseEvent):
@property
def exercisestoppedbytimer(self):
try: return self.ExercisestoppedbytimerEnum(self.exercisestoppedbytimerRaw)
try:
return self.ExercisestoppedbytimerEnum(self.exercisestoppedbytimerRaw)
except ValueError as e:
logger.error("Invalid exercisestoppedbytimerRaw in Exercisestoppedbytimer for "+str(self))
logger.error(e)
@@ -2591,7 +2633,8 @@ class LidAaUserModeChange(BaseEvent):
@property
def activesleepschedule(self):
try: return self.ActivesleepscheduleBitmask(self.activesleepscheduleRaw)
try:
return self.ActivesleepscheduleBitmask(self.activesleepscheduleRaw)
except ValueError as e:
logger.error("Invalid activesleepscheduleRaw in ActivesleepscheduleBitmask for "+str(self))
logger.error(e)
@@ -2608,7 +2651,8 @@ class LidAaUserModeChange(BaseEvent):
@property
def eatingsoonstoppedbytimer(self):
try: return self.EatingsoonstoppedbytimerEnum(self.eatingsoonstoppedbytimerRaw)
try:
return self.EatingsoonstoppedbytimerEnum(self.eatingsoonstoppedbytimerRaw)
except ValueError as e:
logger.error("Invalid eatingsoonstoppedbytimerRaw in Eatingsoonstoppedbytimer for "+str(self))
logger.error(e)
@@ -2678,7 +2722,8 @@ class LidAaPcmChange(BaseEvent):
@property
def currentpcm(self):
try: return self.CurrentpcmEnum(self.currentpcmRaw)
try:
return self.CurrentpcmEnum(self.currentpcmRaw)
except ValueError as e:
logger.error("Invalid currentpcmRaw in Currentpcm for "+str(self))
logger.error(e)
@@ -2699,7 +2744,8 @@ class LidAaPcmChange(BaseEvent):
@property
def previouspcm(self):
try: return self.PreviouspcmEnum(self.previouspcmRaw)
try:
return self.PreviouspcmEnum(self.previouspcmRaw)
except ValueError as e:
logger.error("Invalid previouspcmRaw in Previouspcm for "+str(self))
logger.error(e)
@@ -2716,7 +2762,8 @@ class LidAaPcmChange(BaseEvent):
@property
def pumpsuspended(self):
try: return self.PumpsuspendedEnum(self.pumpsuspendedRaw)
try:
return self.PumpsuspendedEnum(self.pumpsuspendedRaw)
except ValueError as e:
logger.error("Invalid pumpsuspendedRaw in Pumpsuspended for "+str(self))
logger.error(e)
@@ -2733,7 +2780,8 @@ class LidAaPcmChange(BaseEvent):
@property
def calculationavailable(self):
try: return self.CalculationavailableEnum(self.calculationavailableRaw)
try:
return self.CalculationavailableEnum(self.calculationavailableRaw)
except ValueError as e:
logger.error("Invalid calculationavailableRaw in Calculationavailable for "+str(self))
logger.error(e)
@@ -2750,7 +2798,8 @@ class LidAaPcmChange(BaseEvent):
@property
def cgmavailable(self):
try: return self.CgmavailableEnum(self.cgmavailableRaw)
try:
return self.CgmavailableEnum(self.cgmavailableRaw)
except ValueError as e:
logger.error("Invalid cgmavailableRaw in Cgmavailable for "+str(self))
logger.error(e)
@@ -2767,7 +2816,8 @@ class LidAaPcmChange(BaseEvent):
@property
def closedlooppreferred(self):
try: return self.ClosedlooppreferredEnum(self.closedlooppreferredRaw)
try:
return self.ClosedlooppreferredEnum(self.closedlooppreferredRaw)
except ValueError as e:
logger.error("Invalid closedlooppreferredRaw in Closedlooppreferred for "+str(self))
logger.error(e)
@@ -2784,7 +2834,8 @@ class LidAaPcmChange(BaseEvent):
@property
def sufficientclosedloopparams(self):
try: return self.SufficientclosedloopparamsEnum(self.sufficientclosedloopparamsRaw)
try:
return self.SufficientclosedloopparamsEnum(self.sufficientclosedloopparamsRaw)
except ValueError as e:
logger.error("Invalid sufficientclosedloopparamsRaw in Sufficientclosedloopparams for "+str(self))
logger.error(e)
@@ -2850,7 +2901,8 @@ class LidCgmDataGxb(BaseEvent):
@property
def glucosevaluestatus(self):
try: return self.GlucosevaluestatusEnum(self.glucosevaluestatusRaw)
try:
return self.GlucosevaluestatusEnum(self.glucosevaluestatusRaw)
except ValueError as e:
logger.error("Invalid glucosevaluestatusRaw in Glucosevaluestatus for "+str(self))
logger.error(e)
@@ -2873,7 +2925,8 @@ class LidCgmDataGxb(BaseEvent):
@property
def cgmDataType(self):
try: return self.CgmdatatypeBitmask(self.cgmDataTypeRaw)
try:
return self.CgmdatatypeBitmask(self.cgmDataTypeRaw)
except ValueError as e:
logger.error("Invalid cgmDataTypeRaw in CgmdatatypeBitmask for "+str(self))
logger.error(e)
@@ -2908,7 +2961,8 @@ class LidCgmDataGxb(BaseEvent):
@property
def egvInfoBitmask(self):
try: return self.EgvinfobitmaskBitmask(self.egvInfoBitmaskRaw)
try:
return self.EgvinfobitmaskBitmask(self.egvInfoBitmaskRaw)
except ValueError as e:
logger.error("Invalid egvInfoBitmaskRaw in EgvinfobitmaskBitmask for "+str(self))
logger.error(e)
@@ -2978,7 +3032,8 @@ class LidBasalDelivery(BaseEvent):
@property
def commandedRateSource(self):
try: return self.CommandedratesourceEnum(self.commandedRateSourceRaw)
try:
return self.CommandedratesourceEnum(self.commandedRateSourceRaw)
except ValueError as e:
logger.error("Invalid commandedRateSourceRaw in Commandedratesource for "+str(self))
logger.error(e)
@@ -3039,7 +3094,8 @@ class LidBolusDelivery(BaseEvent):
@property
def bolusDeliveryStatus(self):
try: return self.BolusdeliverystatusEnum(self.bolusDeliveryStatusRaw)
try:
return self.BolusdeliverystatusEnum(self.bolusDeliveryStatusRaw)
except ValueError as e:
logger.error("Invalid bolusDeliveryStatusRaw in Bolusdeliverystatus for "+str(self))
logger.error(e)
@@ -3064,7 +3120,8 @@ class LidBolusDelivery(BaseEvent):
@property
def bolusType(self):
try: return self.BolustypeBitmask(self.bolusTypeRaw)
try:
return self.BolustypeBitmask(self.bolusTypeRaw)
except ValueError as e:
logger.error("Invalid bolusTypeRaw in BolustypeBitmask for "+str(self))
logger.error(e)
@@ -3093,7 +3150,8 @@ class LidBolusDelivery(BaseEvent):
@property
def bolusSource(self):
try: return self.BolussourceEnum(self.bolusSourceRaw)
try:
return self.BolussourceEnum(self.bolusSourceRaw)
except ValueError as e:
logger.error("Invalid bolusSourceRaw in Bolussource for "+str(self))
logger.error(e)
@@ -3198,7 +3256,8 @@ class LidAaDailyStatus(BaseEvent):
@property
def pumpcontrolstate(self):
try: return self.PumpcontrolstateEnum(self.pumpcontrolstateRaw)
try:
return self.PumpcontrolstateEnum(self.pumpcontrolstateRaw)
except ValueError as e:
logger.error("Invalid pumpcontrolstateRaw in Pumpcontrolstate for "+str(self))
logger.error(e)
@@ -3217,7 +3276,8 @@ class LidAaDailyStatus(BaseEvent):
@property
def usermode(self):
try: return self.UsermodeEnum(self.usermodeRaw)
try:
return self.UsermodeEnum(self.usermodeRaw)
except ValueError as e:
logger.error("Invalid usermodeRaw in Usermode for "+str(self))
logger.error(e)
@@ -3238,7 +3298,8 @@ class LidAaDailyStatus(BaseEvent):
@property
def sensortype(self):
try: return self.SensortypeEnum(self.sensortypeRaw)
try:
return self.SensortypeEnum(self.sensortypeRaw)
except ValueError as e:
logger.error("Invalid sensortypeRaw in Sensortype for "+str(self))
logger.error(e)
@@ -3286,7 +3347,8 @@ class LidCgmAlertActivatedDex(BaseEvent):
"20": "CGM Transmitter Error",
"26": "CGM Temperature",
"27": "CGM Failed Connection",
"39": "CGM Transmitter Expired"
"39": "CGM Transmitter Expired",
"40": "Pump Bluetooth Error"
}
class DalertidEnum(Enum):
@@ -3297,10 +3359,12 @@ class LidCgmAlertActivatedDex(BaseEvent):
CgmTemperature = 26
CgmFailedConnection = 27
CgmTransmitterExpired = 39
PumpBluetoothError = 40
@property
def dalertid(self):
try: return self.DalertidEnum(self.dalertidRaw)
try:
return self.DalertidEnum(self.dalertidRaw)
except ValueError as e:
logger.error("Invalid dalertidRaw in Dalertid for "+str(self))
logger.error(e)
@@ -3319,7 +3383,8 @@ class LidCgmAlertActivatedDex(BaseEvent):
@property
def sensortype(self):
try: return self.SensortypeEnum(self.sensortypeRaw)
try:
return self.SensortypeEnum(self.sensortypeRaw)
except ValueError as e:
logger.error("Invalid sensortypeRaw in Sensortype for "+str(self))
logger.error(e)
@@ -3368,7 +3433,8 @@ class LidCgmAlertClearedDex(BaseEvent):
"20": "CGM Transmitter Error",
"26": "CGM Temperature",
"27": "CGM Failed Connection",
"39": "CGM Transmitter Expired"
"39": "CGM Transmitter Expired",
"40": "Pump Bluetooth Error"
}
class DalertidEnum(Enum):
@@ -3379,10 +3445,12 @@ class LidCgmAlertClearedDex(BaseEvent):
CgmTemperature = 26
CgmFailedConnection = 27
CgmTransmitterExpired = 39
PumpBluetoothError = 40
@property
def dalertid(self):
try: return self.DalertidEnum(self.dalertidRaw)
try:
return self.DalertidEnum(self.dalertidRaw)
except ValueError as e:
logger.error("Invalid dalertidRaw in Dalertid for "+str(self))
logger.error(e)
@@ -3401,7 +3469,8 @@ class LidCgmAlertClearedDex(BaseEvent):
@property
def sensortype(self):
try: return self.SensortypeEnum(self.sensortypeRaw)
try:
return self.SensortypeEnum(self.sensortypeRaw)
except ValueError as e:
logger.error("Invalid sensortypeRaw in Sensortype for "+str(self))
logger.error(e)
@@ -3445,7 +3514,8 @@ class LidCgmAlertAckDex(BaseEvent):
"20": "CGM Transmitter Error",
"26": "CGM Temperature",
"27": "CGM Failed Connection",
"39": "CGM Transmitter Expired"
"39": "CGM Transmitter Expired",
"40": "Pump Bluetooth Error"
}
class DalertidEnum(Enum):
@@ -3456,10 +3526,12 @@ class LidCgmAlertAckDex(BaseEvent):
CgmTemperature = 26
CgmFailedConnection = 27
CgmTransmitterExpired = 39
PumpBluetoothError = 40
@property
def dalertid(self):
try: return self.DalertidEnum(self.dalertidRaw)
try:
return self.DalertidEnum(self.dalertidRaw)
except ValueError as e:
logger.error("Invalid dalertidRaw in Dalertid for "+str(self))
logger.error(e)
@@ -3478,7 +3550,8 @@ class LidCgmAlertAckDex(BaseEvent):
@property
def sensortype(self):
try: return self.SensortypeEnum(self.sensortypeRaw)
try:
return self.SensortypeEnum(self.sensortypeRaw)
except ValueError as e:
logger.error("Invalid sensortypeRaw in Sensortype for "+str(self))
logger.error(e)
@@ -3495,7 +3568,8 @@ class LidCgmAlertAckDex(BaseEvent):
@property
def acksource(self):
try: return self.AcksourceEnum(self.acksourceRaw)
try:
return self.AcksourceEnum(self.acksourceRaw)
except ValueError as e:
logger.error("Invalid acksourceRaw in Acksource for "+str(self))
logger.error(e)
@@ -3553,7 +3627,8 @@ class LidCgmDataFsl2(BaseEvent):
@property
def glucosevaluestatus(self):
try: return self.GlucosevaluestatusEnum(self.glucosevaluestatusRaw)
try:
return self.GlucosevaluestatusEnum(self.glucosevaluestatusRaw)
except ValueError as e:
logger.error("Invalid glucosevaluestatusRaw in Glucosevaluestatus for "+str(self))
logger.error(e)
@@ -3576,7 +3651,8 @@ class LidCgmDataFsl2(BaseEvent):
@property
def cgmDataType(self):
try: return self.CgmdatatypeBitmask(self.cgmDataTypeRaw)
try:
return self.CgmdatatypeBitmask(self.cgmDataTypeRaw)
except ValueError as e:
logger.error("Invalid cgmDataTypeRaw in CgmdatatypeBitmask for "+str(self))
logger.error(e)
@@ -3609,7 +3685,8 @@ class LidCgmDataFsl2(BaseEvent):
@property
def algorithmstate(self):
try: return self.AlgorithmstateEnum(self.algorithmstateRaw)
try:
return self.AlgorithmstateEnum(self.algorithmstateRaw)
except ValueError as e:
logger.error("Invalid algorithmstateRaw in Algorithmstate for "+str(self))
logger.error(e)
@@ -3644,7 +3721,8 @@ class LidCgmDataFsl2(BaseEvent):
@property
def egvInfoBitmask(self):
try: return self.EgvinfobitmaskBitmask(self.egvInfoBitmaskRaw)
try:
return self.EgvinfobitmaskBitmask(self.egvInfoBitmaskRaw)
except ValueError as e:
logger.error("Invalid egvInfoBitmaskRaw in EgvinfobitmaskBitmask for "+str(self))
logger.error(e)
@@ -3747,7 +3825,8 @@ class LidCgmDataG7(BaseEvent):
@property
def glucosevaluestatus(self):
try: return self.GlucosevaluestatusEnum(self.glucosevaluestatusRaw)
try:
return self.GlucosevaluestatusEnum(self.glucosevaluestatusRaw)
except ValueError as e:
logger.error("Invalid glucosevaluestatusRaw in Glucosevaluestatus for "+str(self))
logger.error(e)
@@ -3770,7 +3849,8 @@ class LidCgmDataG7(BaseEvent):
@property
def cgmDataType(self):
try: return self.CgmdatatypeBitmask(self.cgmDataTypeRaw)
try:
return self.CgmdatatypeBitmask(self.cgmDataTypeRaw)
except ValueError as e:
logger.error("Invalid cgmDataTypeRaw in CgmdatatypeBitmask for "+str(self))
logger.error(e)
@@ -3809,7 +3889,8 @@ class LidCgmDataG7(BaseEvent):
@property
def algorithmstate(self):
try: return self.AlgorithmstateEnum(self.algorithmstateRaw)
try:
return self.AlgorithmstateEnum(self.algorithmstateRaw)
except ValueError as e:
logger.error("Invalid algorithmstateRaw in Algorithmstate for "+str(self))
logger.error(e)
@@ -3842,7 +3923,8 @@ class LidCgmDataG7(BaseEvent):
@property
def egvInfoBitmask(self):
try: return self.EgvinfobitmaskBitmask(self.egvInfoBitmaskRaw)
try:
return self.EgvinfobitmaskBitmask(self.egvInfoBitmaskRaw)
except ValueError as e:
logger.error("Invalid egvInfoBitmaskRaw in EgvinfobitmaskBitmask for "+str(self))
logger.error(e)
@@ -4050,7 +4132,8 @@ class LidCgmAlertActivatedFsl2(BaseEvent):
"20": "CGM Transmitter Error",
"26": "CGM Temperature",
"27": "CGM Failed Connection",
"39": "CGM Transmitter Expired"
"39": "CGM Transmitter Expired",
"40": "Pump Bluetooth Error"
}
class DalertidEnum(Enum):
@@ -4061,10 +4144,12 @@ class LidCgmAlertActivatedFsl2(BaseEvent):
CgmTemperature = 26
CgmFailedConnection = 27
CgmTransmitterExpired = 39
PumpBluetoothError = 40
@property
def dalertid(self):
try: return self.DalertidEnum(self.dalertidRaw)
try:
return self.DalertidEnum(self.dalertidRaw)
except ValueError as e:
logger.error("Invalid dalertidRaw in Dalertid for "+str(self))
logger.error(e)
@@ -4081,7 +4166,8 @@ class LidCgmAlertActivatedFsl2(BaseEvent):
@property
def sensortype(self):
try: return self.SensortypeEnum(self.sensortypeRaw)
try:
return self.SensortypeEnum(self.sensortypeRaw)
except ValueError as e:
logger.error("Invalid sensortypeRaw in Sensortype for "+str(self))
logger.error(e)
@@ -4130,7 +4216,8 @@ class LidCgmAlertClearedFsl2(BaseEvent):
"20": "CGM Transmitter Error",
"26": "CGM Temperature",
"27": "CGM Failed Connection",
"39": "CGM Transmitter Expired"
"39": "CGM Transmitter Expired",
"40": "Pump Bluetooth Error"
}
class DalertidEnum(Enum):
@@ -4141,10 +4228,12 @@ class LidCgmAlertClearedFsl2(BaseEvent):
CgmTemperature = 26
CgmFailedConnection = 27
CgmTransmitterExpired = 39
PumpBluetoothError = 40
@property
def dalertid(self):
try: return self.DalertidEnum(self.dalertidRaw)
try:
return self.DalertidEnum(self.dalertidRaw)
except ValueError as e:
logger.error("Invalid dalertidRaw in Dalertid for "+str(self))
logger.error(e)
@@ -4161,7 +4250,8 @@ class LidCgmAlertClearedFsl2(BaseEvent):
@property
def sensortype(self):
try: return self.SensortypeEnum(self.sensortypeRaw)
try:
return self.SensortypeEnum(self.sensortypeRaw)
except ValueError as e:
logger.error("Invalid sensortypeRaw in Sensortype for "+str(self))
logger.error(e)
+8 -2
View File
@@ -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)
+2 -2
View File
@@ -53,7 +53,7 @@ def transform_enum(event_def, name, name_fmt, field, tx):
out += [
'@property',
f'def {name_fmt}(self):',
f' try:'
f' try:',
f' return self.{enumNameFormat(name_fmt)}Enum(self.{name_fmt}Raw)',
f' except ValueError as e:',
f' logger.error("Invalid {name_fmt}Raw in {enumNameFormat(name_fmt)} for "+str(self))',
@@ -89,7 +89,7 @@ def transform_bitmask(event_def, name, name_fmt, field, tx):
out += [
'@property',
f'def {name_fmt}(self):',
f' try:'
f' try:',
f' return self.{enumNameFormat(name_fmt)}Bitmask(self.{name_fmt}Raw)',
f' except ValueError as e:',
f' logger.error("Invalid {name_fmt}Raw in {enumNameFormat(name_fmt)}Bitmask for "+str(self))',
+4 -4
View File
@@ -16,9 +16,9 @@ EXERCISE_EVENTTYPE = "Exercise"
SLEEP_EVENTTYPE = "Sleep"
ALARM_EVENTTYPE = "Alarm"
CGM_ALERT_EVENTTYPE = "CGM Alert"
CGM_START_EVENTTYPE = "CGM Start Session"
CGM_JOIN_EVENTTYPE = "CGM Join Session"
CGM_STOP_EVENTTYPE = "CGM Stop Session"
CGM_START_EVENTTYPE = "Sensor Start"
CGM_JOIN_EVENTTYPE = "Sensor Start"
CGM_STOP_EVENTTYPE = "Sensor Stop"
IOB_ACTIVITYTYPE = "tconnect_iob"
@@ -52,7 +52,7 @@ class NightscoutEntry:
data = {
"eventType": BOLUS_EVENTTYPE,
"created_at": created_at,
"carbs": int(carbs) if carbs else None,
"carbs": int(carbs) if carbs else 0,
"insulin": float(bolus),
"notes": notes,
"enteredBy": ENTERED_BY,
+9 -4
View File
@@ -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:
@@ -0,0 +1,8 @@
def insulin_float_round(amt):
if type(amt) != float:
return amt
return round(amt, 2)
def insulin_milliunits_to_real(amtMilli):
return insulin_float_round(amtMilli / 1000)
+8 -4
View File
@@ -46,23 +46,27 @@ class ProcessTimeRange:
]
def process(self, time_start, time_end):
logger.info(f"ProcessTimeRange {time_start=} {time_end=} {self.tconnect_device_id=} {self.features=}")
logger.info(f"ProcessTimeRange time_start={time_start} time_end={time_end} tconnect_device_id={self.tconnect_device_id} features={self.features}")
pump_events_raw = self.tconnect.tandemsource.pump_events_raw(self.tconnect_device_id, time_start, time_end)
pump_events_decoded = decode_raw_events(pump_events_raw)
logger.info(f"Read {len(pump_events_decoded)=} (est. {len(pump_events_decoded)/EVENT_LEN} events)")
logger.info(f"Read {len(pump_events_decoded)} bytes (est. {len(pump_events_decoded)/EVENT_LEN} events)")
events = Events(pump_events_decoded)
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))
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))
@@ -62,7 +62,7 @@ class ProcessAlarm:
if type(event) == eventtypes.LidAlarmActivated:
return NightscoutEntry.alarm(
created_at = event.eventTimestamp.format(),
reason = event.alarmid,
reason = "%s" % event.alarmid.name,
pump_event_id = "%s" % event.eventId
)
elif type(event) == eventtypes.LidMalfunctionActivated:
@@ -6,6 +6,7 @@ from ... import features
from ...eventparser.generic import Events, decode_raw_events, EVENT_LEN
from ...eventparser.utils import bitmask_to_list
from ...eventparser import events as eventtypes
from .helpers import insulin_float_round, insulin_milliunits_to_real
from ...domain.tandemsource.event_class import EventClass
from ...parser.nightscout import (
BASAL_EVENTTYPE,
@@ -35,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]
@@ -69,7 +74,7 @@ class ProcessBasal:
def basal_to_nsentry(self, start, duration, event):
if type(event) == eventtypes.LidBasalRateChange:
return NightscoutEntry.basal(
value = event.commandedbasalrate,
value = insulin_float_round(event.commandedbasalrate),
duration_mins = duration.seconds / 60,
created_at = start.format(),
reason = ', '.join(bitmask_to_list(event.changetype)),
@@ -77,7 +82,7 @@ class ProcessBasal:
)
if type(event) == eventtypes.LidBasalDelivery:
return NightscoutEntry.basal(
value = event.commandedRate,
value = insulin_milliunits_to_real(event.commandedRate),
duration_mins = duration.seconds / 60,
created_at = start.format(),
reason = ', '.join(bitmask_to_list(event.commandedRateSource)),
@@ -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))
@@ -7,6 +7,7 @@ from ...eventparser.generic import Events, decode_raw_events, EVENT_LEN
from ...eventparser.utils import bitmask_to_list
from ...eventparser import events as eventtypes
from ...domain.tandemsource.event_class import EventClass
from .helpers import insulin_float_round
from ...parser.nightscout import (
BOLUS_EVENTTYPE,
NightscoutEntry
@@ -43,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
@@ -101,10 +102,11 @@ class ProcessBolus:
return NightscoutEntry.bolus(
bolus = bolusCompleted.insulindelivered,
bolus = insulin_float_round(bolusCompleted.insulindelivered),
carbs = bolusRequested1.carbamount if bolusRequested1 and bolusRequested1.carbamount>0 else None,
created_at = bolusCompleted.eventTimestamp.format(),
notes = notes + suffix,
bg = bolusRequested1.BG if bolusRequested1 and bolusRequested1.BG > 0 else None,
pump_event_id = ",".join(event_ids)
)
@@ -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:
@@ -88,7 +88,7 @@ class ProcessCartridge:
def cannula_to_nsentry(self, cannulaFilled):
return NightscoutEntry.sitechange(
created_at = cannulaFilled.eventTimestamp.format(),
reason = "Cannula Filled" + (" (%du primed)" % round(cannulaFilled.primesize) if cannulaFilled.primesize else ""),
reason = "Cannula Filled" + (" (%du primed)" % round(cannulaFilled.primesize, 2) if cannulaFilled.primesize else ""),
pump_event_id = "%s" % cannulaFilled.eventId
)
@@ -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)
@@ -46,7 +46,9 @@ class ProcessCGMAlert:
ns_entries = []
for event in alertEvents:
ns_entries.append(self.alert_to_nsentry(event))
e = self.alert_to_nsentry(event)
if e:
ns_entries.append(e)
return ns_entries
@@ -63,21 +65,28 @@ class ProcessCGMAlert:
return count
def alert_to_nsentry(self, alert):
if not alert.dalertid:
logger.info("ProcessCGMAlert: Skipping alert with unknown dalertid %d: %s" % (alert.dalertidRaw, alert))
return None
if type(alert) == eventtypes.LidCgmAlertActivated:
return NightscoutEntry.cgm_alert(
created_at = alert.eventTimestamp.format(),
reason = ("CGM Alert (%s)" % alert.dalertid) if alert.dalertid else "CGM Alert (Unknown)",
reason = ("CGM Alert (%s)" % alert.dalertid.name) if alert.dalertid else "CGM Alert (Unknown)",
pump_event_id = "%s" % alert.eventId
)
elif type(alert) == eventtypes.LidCgmAlertActivatedDex:
if alert.dalertid == eventtypes.LidCgmAlertActivatedDex.DalertidEnum.CgmOutOfRange:
logger.info("ProcessCGMAlert: Skipping alert with CgmOutOfRange dalertid %d: %s" % (alert.dalertidRaw, alert))
return None
return NightscoutEntry.cgm_alert(
created_at = alert.eventTimestamp.format(),
reason = ("Dexcom CGM Alert (%s)" % alert.dalertid) if alert.dalertid else "Dexcom CGM Alert (Unknown)",
reason = ("Dexcom CGM Alert (%s)" % alert.dalertid.name) if alert.dalertid else "Dexcom CGM Alert (Unknown)",
pump_event_id = "%s" % alert.eventId
)
elif type(alert) == eventtypes.LidCgmAlertActivatedFsl2:
return NightscoutEntry.cgm_alert(
created_at = alert.eventTimestamp.format(),
reason = ("Libre CGM Alert (%s)" % alert.dalertid) if alert.dalertid else "Libre CGM Alert (Unknown)",
reason = ("Libre CGM Alert (%s)" % alert.dalertid.name) if alert.dalertid else "Libre CGM Alert (Unknown)",
pump_event_id = "%s" % alert.eventId
)
@@ -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)
@@ -9,6 +9,8 @@ from ...eventparser import events as eventtypes
from ...domain.tandemsource.event_class import EventClass
from ...parser.nightscout import (
CGM_START_EVENTTYPE,
CGM_JOIN_EVENTTYPE,
CGM_STOP_EVENTTYPE,
NightscoutEntry
)
@@ -26,18 +28,29 @@ class ProcessCGMStartJoinStop:
return features.PUMP_EVENTS in self.features or features.CGM_ALERTS in self.features
def process(self, events, time_start, time_end):
logger.debug("ProcessCGMStartJoinStop: querying for last uploaded entry")
last_upload = self.nightscout.last_uploaded_entry(CGM_START_EVENTTYPE, time_start=time_start, time_end=time_end)
last_upload = None
last_upload_time = None
if last_upload:
last_upload_time = arrow.get(last_upload["created_at"])
logger.info("ProcessCGMStartJoinStop: Last Nightscout cgmstart upload: %s" % last_upload_time)
for eventtype in [CGM_START_EVENTTYPE, CGM_JOIN_EVENTTYPE, CGM_STOP_EVENTTYPE]:
logger.debug("ProcessCGMStartJoinStop: querying for last uploaded entry for %s" % eventtype)
_last_upload = self.nightscout.last_uploaded_entry(eventtype, time_start=time_start, time_end=time_end)
_last_upload_time = None
if _last_upload:
_last_upload_time = arrow.get(_last_upload["created_at"])
if not last_upload_time:
last_upload = _last_upload
last_upload_time = _last_upload_time
elif _last_upload_time > last_upload_time:
last_upload = _last_upload
last_upload_time = _last_upload_time
logger.info("ProcessCGMStartJoinStop: Last Nightscout %s upload: %s" % (eventtype, _last_upload_time))
logger.info("ProcessCGMStartJoinStop: Overall last Nightscout upload: %s %s" % (last_upload_time, last_upload))
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):
+21 -27
View File
@@ -22,7 +22,8 @@ class TestNightscoutEntry(unittest.TestCase):
"created_at": "2021-03-16 00:25:21-04:00",
"carbs": None,
"insulin": None,
"enteredBy": "Pump (tconnectsync)"
"enteredBy": "Pump (tconnectsync)",
"pump_event_id": ""
}
)
@@ -41,7 +42,8 @@ class TestNightscoutEntry(unittest.TestCase):
"created_at": "2021-03-16 12:25:21-04:00",
"carbs": None,
"insulin": None,
"enteredBy": "Pump (tconnectsync)"
"enteredBy": "Pump (tconnectsync)",
"pump_event_id": ""
}
)
@@ -57,7 +59,8 @@ class TestNightscoutEntry(unittest.TestCase):
"carbs": 45,
"insulin": 7.5,
"notes": "",
"enteredBy": "Pump (tconnectsync)"
"enteredBy": "Pump (tconnectsync)",
"pump_event_id": ""
}
)
@@ -72,7 +75,8 @@ class TestNightscoutEntry(unittest.TestCase):
"carbs": 5,
"insulin": 0.5,
"notes": "",
"enteredBy": "Pump (tconnectsync)"
"enteredBy": "Pump (tconnectsync)",
"pump_event_id": ""
}
)
@@ -92,7 +96,8 @@ class TestNightscoutEntry(unittest.TestCase):
"notes": "",
"enteredBy": "Pump (tconnectsync)",
"glucose": "123",
"glucoseType": "Sensor"
"glucoseType": "Sensor",
"pump_event_id": ""
}
)
@@ -111,28 +116,14 @@ class TestNightscoutEntry(unittest.TestCase):
"notes": "",
"enteredBy": "Pump (tconnectsync)",
"glucose": "150",
"glucoseType": "Finger"
"glucoseType": "Finger",
"pump_event_id": ""
}
)
def test_bolus_with_bg_invalid_type(self):
self.assertRaises(InvalidBolusTypeException,
NightscoutEntry.bolus,
bolus=0.5,
carbs=5,
created_at="2021-03-16 12:25:21-04:00",
bg="150")
self.assertRaises(InvalidBolusTypeException,
NightscoutEntry.bolus,
bolus=0.5,
carbs=5,
created_at="2021-03-16 12:25:21-04:00",
bg="150",
bg_type="")
self.assertRaises(InvalidBolusTypeException,
NightscoutEntry.bolus,
NightscoutEntry.bolus,
bolus=0.5,
carbs=5,
created_at="2021-03-16 12:25:21-04:00",
@@ -163,9 +154,10 @@ class TestNightscoutEntry(unittest.TestCase):
"date": 1635041834000,
"dateString": "2021-10-23T22:17:14-0400",
"device": "Pump (tconnectsync)",
"pump_event_id": ""
}
)
def test_sitechange(self):
self.assertEqual(
NightscoutEntry.sitechange(
@@ -176,10 +168,11 @@ class TestNightscoutEntry(unittest.TestCase):
"reason": "reason",
"notes": "reason",
"created_at": "2021-12-05T00:16:35.058Z",
"enteredBy": "Pump (tconnectsync)"
"enteredBy": "Pump (tconnectsync)",
"pump_event_id": ""
}
)
def test_basalsuspension(self):
self.assertEqual(
NightscoutEntry.basalsuspension(
@@ -190,11 +183,12 @@ class TestNightscoutEntry(unittest.TestCase):
"reason": "reason",
"notes": "reason",
"created_at": "2021-12-05T00:16:35.058Z",
"enteredBy": "Pump (tconnectsync)"
"enteredBy": "Pump (tconnectsync)",
"pump_event_id": ""
}
)
def test_profile_store(self):
self.assertEqual(
NightscoutEntry.profile_store(
+10 -10
View File
@@ -16,7 +16,7 @@ def _stub_last_uploaded_entry(eventType, time_start=None, time_end=None):
class TestNsWritePumpEvents(unittest.TestCase):
SITE_CHANGE_EVENT = {'time': '2024-02-04 16:27:50-05:00', 'event_type': 'Site/Cartridge Change'}
SITE_CHANGE_NS = {'created_at': '2024-02-04 16:27:50-05:00', 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Site Change', 'notes': 'Site/Cartridge Change','reason': 'Site/Cartridge Change'}
SITE_CHANGE_NS = {'created_at': '2024-02-04 16:27:50-05:00', 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Site Change', 'notes': 'Site/Cartridge Change','reason': 'Site/Cartridge Change', 'pump_event_id': ''}
def test_write_single_sitechange_event(self):
nightscout = NightscoutApi()
nightscout.last_uploaded_entry = _stub_last_uploaded_entry
@@ -31,7 +31,7 @@ class TestNsWritePumpEvents(unittest.TestCase):
}, dict(nightscout.uploaded_entries))
EMPTY_CART_EVENT = {'time': '2024-05-14 09:01:59-04:00', 'event_type': 'Empty Cartridge/Pump Shutdown'}
EMPTY_CART_NS = {'created_at': '2024-05-14 09:01:59-04:00', 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Basal Suspension', 'notes': 'Empty Cartridge/Pump Shutdown', 'reason': 'Empty Cartridge/Pump Shutdown'}
EMPTY_CART_NS = {'created_at': '2024-05-14 09:01:59-04:00', 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Basal Suspension', 'notes': 'Empty Cartridge/Pump Shutdown', 'reason': 'Empty Cartridge/Pump Shutdown', 'pump_event_id': ''}
def test_write_single_emptycart_event(self):
nightscout = NightscoutApi()
nightscout.last_uploaded_entry = _stub_last_uploaded_entry
@@ -46,7 +46,7 @@ class TestNsWritePumpEvents(unittest.TestCase):
}, dict(nightscout.uploaded_entries))
USER_SUSPENDED_EVENT = {'time': '2024-02-05 09:48:22-05:00', 'event_type': 'User Suspended'}
USER_SUSPENDED_NS = {'created_at': '2024-02-05 09:48:22-05:00', 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Basal Suspension', 'notes': 'User Suspended', 'reason': 'User Suspended'}
USER_SUSPENDED_NS = {'created_at': '2024-02-05 09:48:22-05:00', 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Basal Suspension', 'notes': 'User Suspended', 'reason': 'User Suspended', 'pump_event_id': ''}
def test_write_single_usersuspended_event(self):
nightscout = NightscoutApi()
nightscout.last_uploaded_entry = _stub_last_uploaded_entry
@@ -59,11 +59,11 @@ class TestNsWritePumpEvents(unittest.TestCase):
self.USER_SUSPENDED_NS
]
}, dict(nightscout.uploaded_entries))
EXERCISE_EVENT = {'time': '2024-03-10 08:53:20-04:00', 'duration_mins': 269.3833333333333, 'event_type': 'Exercise'}
EXERCISE_NS = {'created_at': '2024-03-10 08:53:20-04:00', 'duration': 269.3833333333333, 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Exercise', 'notes': 'Exercise', 'reason': 'Exercise'}
EXERCISE_NS = {'created_at': '2024-03-10 08:53:20-04:00', 'duration': 269.3833333333333, 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Exercise', 'notes': 'Exercise', 'reason': 'Exercise', 'pump_event_id': ''}
EXERCISE_EXTENDED_EVENT = {'time': '2024-03-10 08:53:20-04:00', 'duration_mins': 585.8833333333333, 'event_type': 'Exercise'}
EXERCISE_EXTENDED_NS = {'created_at': '2024-03-10 08:53:20-04:00', 'duration': 585.8833333333333, 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Exercise', 'notes': 'Exercise', 'reason': 'Exercise'}
EXERCISE_EXTENDED_NS = {'created_at': '2024-03-10 08:53:20-04:00', 'duration': 585.8833333333333, 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Exercise', 'notes': 'Exercise', 'reason': 'Exercise', 'pump_event_id': ''}
def test_write_exercise_events(self):
nightscout = NightscoutApi()
nightscout.last_uploaded_entry = _stub_last_uploaded_entry
@@ -101,11 +101,11 @@ class TestNsWritePumpEvents(unittest.TestCase):
self.EXERCISE_EXTENDED_NS
]
}, dict(nightscout.uploaded_entries))
SLEEP_EVENT = {'time': '2024-02-07 00:00:19-05:00', 'duration_mins': 13.916666666666666, 'event_type': 'Sleep'}
SLEEP_NS = {'created_at': '2024-02-07 00:00:19-05:00', 'duration': 13.916666666666666, 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Sleep', 'notes': 'Sleep', 'reason': 'Sleep'}
SLEEP_NS = {'created_at': '2024-02-07 00:00:19-05:00', 'duration': 13.916666666666666, 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Sleep', 'notes': 'Sleep', 'reason': 'Sleep', 'pump_event_id': ''}
SLEEP_EXTENDED_EVENT = {'time': '2024-02-07 00:00:19-05:00', 'duration_mins': 74.0, 'event_type': 'Sleep'}
SLEEP_EXTENDED_NS = {'created_at': '2024-02-07 00:00:19-05:00', 'duration': 74.0, 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Sleep', 'notes': 'Sleep', 'reason': 'Sleep'}
SLEEP_EXTENDED_NS = {'created_at': '2024-02-07 00:00:19-05:00', 'duration': 74.0, 'enteredBy': 'Pump (tconnectsync)', 'eventType': 'Sleep', 'notes': 'Sleep', 'reason': 'Sleep', 'pump_event_id': ''}
def test_write_sleep_events(self):
nightscout = NightscoutApi()
nightscout.last_uploaded_entry = _stub_last_uploaded_entry
@@ -143,7 +143,7 @@ class TestNsWritePumpEvents(unittest.TestCase):
self.SLEEP_EXTENDED_NS
]
}, dict(nightscout.uploaded_entries))
if __name__ == '__main__':
unittest.main()
+15 -15
View File
@@ -26,7 +26,7 @@ class TestProcessTimeRange(unittest.TestCase):
def stub_therapy_timeline(self, time_start, time_end):
return copy.deepcopy(TestBasalSync.base)
def stub_ciq_therapy_events(self, time_start, time_end):
return {
"event": []
@@ -39,7 +39,7 @@ class TestProcessTimeRange(unittest.TestCase):
"basalData": [],
"bolusData": []
}
def stub_ws2_basalsuspension(self, time_start, time_end):
return {"BasalSuspension": []}
@@ -394,7 +394,7 @@ class TestProcessTimeRange(unittest.TestCase):
self.assertDictEqual(nightscout.put_entries, {})
self.assertListEqual(nightscout.deleted_entries, [])
self.assertEqual(count, 0)
"""Existing IOB in Nightscout. Uploads new iob reading and deletes old IOB."""
def test_updates_ciq_iob_data(self):
tconnect = TConnectApi()
@@ -442,7 +442,7 @@ class TestProcessTimeRange(unittest.TestCase):
"activity/sentinel_existing_iob_id"
])
self.assertEqual(count, 1)
"""No pump activity events in Nightscout. New CIQ activity events."""
def test_new_ciq_activity_events(self):
tconnect = TConnectApi()
@@ -460,7 +460,7 @@ class TestProcessTimeRange(unittest.TestCase):
"events": [{
"duration": 1200,
"eventType": 2, # Exercise
"continuation": None,
"continuation": None,
"timeZoneId": "America/Los_Angeles",
"x": 1619901912 # 2021-05-01 13:45:12-04:00
}, {
@@ -510,7 +510,7 @@ class TestProcessTimeRange(unittest.TestCase):
"events": [{
"duration": 1200,
"eventType": 2, # Exercise
"continuation": None,
"continuation": None,
"timeZoneId": "America/Los_Angeles",
"x": 1619901912 # 2021-05-01 13:45:12-04:00
}, {
@@ -539,7 +539,7 @@ class TestProcessTimeRange(unittest.TestCase):
self.assertListEqual(nightscout.deleted_entries, [])
self.assertEqual(count, 0)
"""
Existing Sleep event in Nightscout with shorter duration than current, as well as a past Exercise event.
Ensures that the old sleep event is deleted and a new one is created with the correct duration."""
@@ -559,7 +559,7 @@ class TestProcessTimeRange(unittest.TestCase):
"events": [{
"duration": 1200,
"eventType": 2, # Exercise
"continuation": None,
"continuation": None,
"timeZoneId": "America/Los_Angeles",
"x": 1619901912 # 2021-05-01 13:45:12-04:00
}, {
@@ -623,7 +623,7 @@ class TestProcessTimeRange(unittest.TestCase):
tconnect.controliq.therapy_timeline = self.stub_therapy_timeline
tconnect.ws2.therapy_timeline_csv = self.stub_therapy_timeline_csv
def fake_basalsuspension(time_start, time_end):
def fake_basalsuspension(time_start, time_end):
self.assertEqual(time_start, start)
self.assertEqual(time_end, end)
@@ -673,7 +673,7 @@ class TestProcessTimeRange(unittest.TestCase):
tconnect.controliq.therapy_timeline = self.stub_therapy_timeline
tconnect.ws2.therapy_timeline_csv = self.stub_therapy_timeline_csv
def fake_basalsuspension(time_start, time_end):
def fake_basalsuspension(time_start, time_end):
self.assertEqual(time_start, start)
self.assertEqual(time_end, end)
@@ -737,7 +737,7 @@ class TestProcessTimeRange(unittest.TestCase):
tconnect.controliq.therapy_timeline = self.stub_therapy_timeline
tconnect.ws2.therapy_timeline_csv = self.stub_therapy_timeline_csv
def fake_basalsuspension(time_start, time_end):
def fake_basalsuspension(time_start, time_end):
self.assertEqual(time_start, start)
self.assertEqual(time_end, end)
@@ -781,7 +781,7 @@ class TestProcessTimeRange(unittest.TestCase):
pump_guid = '00000000-0000-0000-0000-000000000001'
serial_number = '12345'
def fake_my_devices():
return {
serial_number: Device(
@@ -830,7 +830,7 @@ class TestProcessTimeRange(unittest.TestCase):
pump_guid = '00000000-0000-0000-0000-000000000001'
serial_number = '12345'
def fake_my_devices():
return {
serial_number: Device(
@@ -878,7 +878,7 @@ class TestProcessTimeRange(unittest.TestCase):
pump_guid = '00000000-0000-0000-0000-000000000001'
serial_number = '12345'
def fake_my_devices():
return {
serial_number: Device(
@@ -932,7 +932,7 @@ class TestProcessTimeRange(unittest.TestCase):
pump_guid = '00000000-0000-0000-0000-000000000001'
serial_number = '12345'
def fake_my_devices():
return {
serial_number: Device(