Skip to content

Commit

Permalink
added constants and description needed to parse database schemata
Browse files Browse the repository at this point in the history
  • Loading branch information
DorianScholz committed Aug 8, 2017
1 parent 17e0b09 commit 8799839
Show file tree
Hide file tree
Showing 2 changed files with 243 additions and 6 deletions.
200 changes: 198 additions & 2 deletions lib/drivers/abbott/freeStyleLibreConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,18 @@ ERROR_DESCRIPTION[ERROR.CMD_FAILED] = 'Command failed!';
ERROR_DESCRIPTION[ERROR.CRC_ERROR] = 'Wrong checksum!';
ERROR_DESCRIPTION[ERROR.INVALID_ID] = 'Wrong table ID!';

export const FIELD_ID = {
// for CFG and DB fields
export const FIELD_TYPE = {
UNSIGNED_DECIMAL: 0, // uint
UNSIGNED_HEX: 1, // uint (display as hex)
SIGNED_DECIMAL: 2, // int
UTF8: 3, // string
BULK_DATA : 4, // bytes
CRC32: 10, // uint32
CRC16: 11 // uint16
};

export const DB_FIELD_ID = {
RECORD_NUMBER: 0,
TIME_VALID: 7,
TYPE: 8,
Expand Down Expand Up @@ -167,7 +178,7 @@ export const FIELD_ID = {
EVENT_CRC: 253
};

export const RECORD_TYPE = {
export const DB_RECORD_TYPE = {
COMMON_HDR_SCHEMA: 255,
GLUCOSE_KETONE_SERVING_SCHEMA: 0,
GLUCOSE_KETONE_MEAL_SCHEMA: 1,
Expand Down Expand Up @@ -216,6 +227,191 @@ export const CFG_TABLE_ID = {
REMINDER_DATA: 10
};

export const CFG_FIELD_ID = {
SYSTEM_TYPE: 1025,
MARKET_LEVEL: 1026,
MARKET_SUB_LEVEL: 1027,
MARKET_PUCK_LEVEL: 1028,
BRAND_NAME: 1029,
NUMBER_FORMAT: 1056,
UOM: 1057,
INSULIN_CALC_PRESENT: 1058,
ALLOWABLE_MEAL_UNIT: 1059,
GLYCEMIC_RANGE_HIGH: 1067,
GLYCEMIC_RANGE_LOW: 1068,
TIME_CONVERSION: 1072,
FIRST_TIME_STARTUP_DONE: 1106,
PATIENT_NAME: 1130,
PATIENT_ID: 1131,
TARGET_RANGE_LOW: 1132,
TARGETRANGE_HIGH: 1133,
LANGUAGE_SETTING: 1134,
TIME_FORMAT: 1135,
INSULIN_DOSE_INCREMENT: 1136,
MASK_MODE_OPTION: 1137,
MASK_MODE_REMINDER: 1138,
MASK_MODE_HOUR: 1139,
MASK_MODE_MIN: 1140,
BEEPER_VOLUME: 1160,
NOTIFICATION_SOUND: 1161,
NOTIFICATION_VIBE: 1162,
BUTTON_SOUND: 1163,
INSULIN_MODE: 1190,
EASY_DONE_FLAG: 1191,
ADVANCE_DONE_FLAG: 1192,
CARB_TYPE: 1193,
CARBS_PER_SERVING: 1194,
CARB_RATIO_FLAG: 1195,
CARB_RATIO_ALL_DAY: 1196,
CARB_RATIO_MORNING: 1197,
CARB_RATIO_MIDDAY: 1198,
CARB_RATIO_EVENING: 1199,
CARB_RATIO_NIGHT: 1200,
SERVING_RATIO_FLAG: 1201,
SERVING_RATIO_ALL_DAY: 1202,
SERVING_RATIO_MORNING: 1203,
SERVING_RATIO_MIDDAY: 1204,
SERVING_RATIO_EVENING: 1205,
SERVING_RATIO_NIGHT: 1206,
IOB_ICON_FLAG: 1207,
INSULIN_DURATION: 1208,
FIXED_DOSE_BREAKFAST: 1209,
FIXED_DOSE_LUNCH: 1210,
FIXED_DOES_DINNER: 1211,
CORRECTION_FACTORS_REQ: 1212,
CORRECTION_TYPE: 1213,
SINGLE_TARGET_RATIO_FLAG: 1214,
SINGLE_TARGET_RATIO_ALL_DAY: 1215,
SINGLE_TARGET_RATIO_MORNING: 1216,
SINGLE_TARGET_RATIO_MIDDAY: 1217,
SINGLE_TARGET_RATIO_EVENING: 1218,
SINGLE_TARGET_RATIO_NIGHT: 1219,
LOW_TARGET_RATIO_FLAG: 1220,
LOW_TARGET_RATIO_ALL_DAY: 1221,
LOW_TARGET_RATIO_MORNING: 1222,
LOW_TARGET_RATIO_MIDDAY: 1223,
LOW_TARGET_RATIO_EVENING: 1224,
LOW_TARGET_RATIO_NIGHT: 1225,
HIGH_TARGET_RATIO_FLAG: 1226,
HIGH_TARGET_RATIO_ALL_DAY: 1227,
HIGH_TARGET_RATIO_MORNING: 1228,
HIGH_TARGET_RATIO_MIDDAY: 1229,
HIGH_TARGET_RATIO_EVENING: 1230,
HIGH_TARGET_RATIO_NIGHT: 1231,
BG_DROP_CORRECTION_RATIO_FLAG: 1232,
BG_DROP_ALL_DAY: 1233,
BG_DROP_MORNING: 1234,
BG_DROP_MIDDAY: 1235,
BG_DROP_EVENING: 1236,
BG_DROP_NIGHT: 1237,
REMINDER_STRING_0: 1260,
REMINDER_STRING_1: 1261,
REMINDER_STRING_2: 1262,
REMINDER_STRING_3: 1263,
REMINDER_STRING_4: 1264,
REMINDER_STRING_5: 1265,
REMINDER_STRING_6: 1266,
REMINDER_STRING_7: 1267,
REMINDER_STRING_8: 1268,
REMINDER_STRING_9: 1269,
REMINDER_STRING_10: 1270,
REMINDER_STRING_11: 1271,
SMART_TAG_0: 1290,
SMART_TAG_1: 1291,
SMART_TAG_2: 1292,
SMART_TAG_3: 1293,
SMART_TAG_4: 1294,
SMART_TAG_5: 1295,
BULK_STORAGE: 1310,
SESNOR_STATE: 1320,
SENSOR_UID: 1321,
PAIRED_FLAG: 1322,
SESNOR_PUCK_INFO: 1323,
SESNOR_START_TIME: 1324,
REMINDER_CUSTOM_STRING_1: 1400,
REMINDER_CUSTOM_STRING_2: 1401,
REMINDER_CUSTOM_STRING_3: 1402,
REMINDER_CUSTOM_STRING_4: 1403,
REMINDER_CUSTOM_STRING_5: 1404,
REMINDER_CUSTOM_STRING_6: 1405,
REMINDER_CUSTOM_STRING_7: 1406,
REMINDER_CUSTOM_STRING_8: 1407,
REMINDER_CUSTOM_STRING_9: 1408,
REMINDER_1_DATA_TYPE: 1415,
REMINDER_1_DATA_STRING_INDEX: 1416,
REMINDER_1_DATA_TIME_HOUR: 1417,
REMINDER_1_DATA_TIME_MINUTE: 1418,
REMINDER_1_DATA_TIME_SECOND: 1419,
REMINDER_1_DATA_STATUS: 1475,
REMINDER_2_DATA_TYPE: 1420,
REMINDER_2_DATA_STRING_INDEX: 1421,
REMINDER_2_DATA_TIME_HOUR: 1422,
REMINDER_2_DATA_TIME_MINUTE: 1423,
REMINDER_2_DATA_TIME_SECOND: 1424,
REMINDER_2_DATA_STATUS: 1476,
REMINDER_3_DATA_TYPE: 1425,
REMINDER_3_DATA_STRING_INDEX: 1426,
REMINDER_3_DATA_TIME_HOUR: 1427,
REMINDER_3_DATA_TIME_MINUTE: 1428,
REMINDER_3_DATA_TIME_SECOND: 1429,
REMINDER_3_DATA_STATUS: 1477,
REMINDER_4_DATA_TYPE: 1430,
REMINDER_4_DATA_STRING_INDEX: 1431,
REMINDER_4_DATA_TIME_HOUR: 1432,
REMINDER_4_DATA_TIME_MINUTE: 1433,
REMINDER_4_DATA_TIME_SECOND: 1434,
REMINDER_4_DATA_STATUS: 1478,
REMINDER_5_DATA_TYPE: 1435,
REMINDER_5_DATA_STRING_INDEX: 1436,
REMINDER_5_DATA_TIME_HOUR: 1437,
REMINDER_5_DATA_TIME_MINUTE: 1438,
REMINDER_5_DATA_TIME_SECOND: 1439,
REMINDER_5_DATA_STATUS: 1479,
REMINDER_6_DATA_TYPE: 1440,
REMINDER_6_DATA_STRING_INDEX: 1441,
REMINDER_6_DATA_TIME_HOUR: 1442,
REMINDER_6_DATA_TIME_MINUTE: 1443,
REMINDER_6_DATA_TIME_SECOND: 1444,
REMINDER_6_DATA_STATUS: 1480,
REMINDER_7_DATA_TYPE: 1445,
REMINDER_7_DATA_STRING_INDEX: 1446,
REMINDER_7_DATA_TIME_HOUR: 1447,
REMINDER_7_DATA_TIME_MINUTE: 1448,
REMINDER_7_DATA_TIME_SECOND: 1449,
REMINDER_7_DATA_STATUS: 1481,
REMINDER_8_DATA_TYPE: 1450,
REMINDER_8_DATA_STRING_INDEX: 1451,
REMINDER_8_DATA_TIME_HOUR: 1452,
REMINDER_8_DATA_TIME_MINUTE: 1453,
REMINDER_8_DATA_TIME_SECOND: 1454,
REMINDER_8_DATA_STATUS: 1482,
REMINDER_9_DATA_TYPE: 1455,
REMINDER_9_DATA_STRING_INDEX: 1456,
REMINDER_9_DATA_TIME_HOUR: 1457,
REMINDER_9_DATA_TIME_MINUTE: 1458,
REMINDER_9_DATA_TIME_SECOND: 1459,
REMINDER_9_DATA_STATUS: 1483,
REMINDER_10_DATA_TYPE: 1460,
REMINDER_10_DATA_STRING_INDEX: 1461,
REMINDER_10_DATA_TIME_HOUR: 1462,
REMINDER_10_DATA_TIME_MINUTE: 1463,
REMINDER_10_DATA_TIME_SECOND: 1464,
REMINDER_10_DATA_STATUS: 1484,
REMINDER_11_DATA_TYPE: 1465,
REMINDER_11_DATA_STRING_INDEX: 1466,
REMINDER_11_DATA_TIME_HOUR: 1467,
REMINDER_11_DATA_TIME_MINUTE: 1468,
REMINDER_11_DATA_TIME_SECOND: 1469,
REMINDER_11_DATA_STATUS: 1485,
REMINDER_12_DATA_TYPE: 1470,
REMINDER_12_DATA_STRING_INDEX: 1471,
REMINDER_12_DATA_TIME_HOUR: 1472,
REMINDER_12_DATA_TIME_MINUTE: 1473,
REMINDER_12_DATA_TIME_SECOND: 1474,
REMINDER_12_DATA_STATUS: 1486,
CONFIG_CRC: 2047
};

export const CRC32_TABLE = [
0x00000000,
0x04c11db7,
Expand Down
49 changes: 45 additions & 4 deletions lib/drivers/abbott/freeStyleLibreData.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import sundial from 'sundial';

import TZOUtil from '../../TimezoneOffsetUtil';

import {OP_CODE, ERROR_DESCRIPTION, RECORD_TYPE, CFG_TABLE_ID} from './freeStyleLibreConstants';
import {OP_CODE, ERROR_DESCRIPTION, DB_RECORD_TYPE, CFG_TABLE_ID} from './freeStyleLibreConstants';

const FORMAT = {
ERROR: 'bb',
Expand All @@ -35,6 +35,18 @@ const FORMAT = {
HISTORICAL_DATA: 'ssss',
};

const BITFIELD = {
RECORD_HEADER: {
recordNumber: {
signed: false,
bitLength: 16,
byteOffset: 0,
bitOffset: 0
}
}
};


const FORMAT_LENGTH = _.mapValues(FORMAT, format => { return struct.structlen(format); });

export class FreeStyleLibreData {
Expand Down Expand Up @@ -98,8 +110,37 @@ export class FreeStyleLibreData {
}

handleDatabaseSchema(aapPacket) {
// these are ignored for now, as the schemata are already know from the specs
// for now they are hardcoded based on the specs for the few record types that are actually needed
/*
* These are ignored for now, as the schemata are already known from the specs.
* For now they are hardcoded based on the specs for the few record types that are actually needed.
*
* The schemata describe the fields in the database records, so that using this information to parse the records
* instead of the hardcoded format strings, would make it possible to understand the data even after a potential
* firmware upgrade that changes the database structure.
* (As long as the field IDs stay the same, the fields parsed via these schemata can still be evaluated properly.)
*
* Schema description: (example: the record header prefixed to all records)
*
UINT8 RecordHeader_schema[] =
{
// schema descriptor
48, 0, // [uint16_le] schema table length (including this descriptor)
1, 0, // [uint16_le] schema table version
255, // [uint8] schema table/record ID
6, 0, // [uint16_le] number of data words (16bit) in the record
5, // [uint8] number of fields in the record
// field descriptors (8 byte each)
// [uint16_le], [uint16_le], [uint8], [uint8], [uint16_le]
// field ID, word offset, bit offset inside the word, data type, data length in bits
0,0,0,0,0,1,16,0,
8,0,1,0,0,0,8,0,
7,0,1,0,15,0,1,0,
9,0,2,0,0,0,32,0,
10,0,4,0,0,2,32,0
};
*
*/
}

handleDatabase(aapPacket) {
Expand All @@ -125,7 +166,7 @@ export class FreeStyleLibreData {
headerFields.timezoneOffset = utcInfo.timezoneOffset;
headerFields.conversionOffset = utcInfo.conversionOffset;

if (headerFields.recordType === RECORD_TYPE.HISTORICAL_DATA_SCHEMA) {
if (headerFields.recordType === DB_RECORD_TYPE.HISTORICAL_DATA_SCHEMA) {
const historyFields = struct.unpack(aapPacket.data, offset, FORMAT.HISTORICAL_DATA,
['glucoseValue', 'lifeCounter', 'dataQualityErrorFlags', 'CRC16']);
historyFields.firstFlag = ((historyFields.glucoseValue & 0x1000) > 0);
Expand Down

0 comments on commit 8799839

Please sign in to comment.