• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nightscout / cgm-remote-monitor / 4954

pending completion
4954

push

travis-ci

jasoncalabrese
Merge pull request #1565 from nightscout/wip/openaps-fields

add fields/retro-fields extended settings to the openaps plugin

23 of 23 new or added lines in 1 file covered. (100.0%)

4208 of 7225 relevant lines covered (58.24%)

18.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

11.76
/lib/plugins/cob.js
1
'use strict';
2

3
var _ = require('lodash')
1✔
4
  , iob = require('./iob')()
5
  , moment = require('moment');
6

7
function init() {
1✔
8

9
  var cob = {
23✔
10
    name: 'cob'
11
    , label: 'Carbs-on-Board'
12
    , pluginType: 'pill-minor'
13
  };
14

15
  cob.setProperties = function setProperties(sbx) {
23✔
16
    sbx.offerProperty('cob', function setCOB ( ) {
×
17
      return cob.cobTotal(sbx.data.treatments, sbx.data.profile, sbx.time);
×
18
    });
19
  };
20

21
  cob.cobTotal = function cobTotal(treatments, profile, time, spec_profile) {
23✔
22

23
    if (!profile || !profile.hasData()) {
×
24
      console.warn('For the COB plugin to function you need a treatment profile');
×
25
      return {};
×
26
    }
27

28
    if (!profile.getSensitivity(time, spec_profile) || !profile.getCarbRatio(time, spec_profile)) {
×
29
      console.warn('For the CPB plugin to function your treatment profile must have both sens and carbratio fields');
×
30
      return {};
×
31
    }
32

33
    // TODO: figure out the liverSensRatio that gives the most accurate purple line predictions
34
    var liverSensRatio = 8;
×
35
    var totalCOB = 0;
×
36
    var lastCarbs = null;
×
37

38
    if (!treatments) {
×
39
      return {};
×
40
    }
41

42
    if (typeof time === 'undefined') {
×
43
      time = Date.now();
×
44
    }
45

46
    var isDecaying = 0;
×
47
    var lastDecayedBy = 0;
×
48

49
    _.each(treatments, function eachTreatment(treatment) {
×
50
      if (treatment.carbs && treatment.mills < time) {
×
51
        lastCarbs = treatment;
×
52
        var cCalc = cob.cobCalc(treatment, profile, lastDecayedBy, time, spec_profile);
×
53
        var decaysin_hr = (cCalc.decayedBy - time) / 1000 / 60 / 60;
×
54
        if (decaysin_hr > -10) {
×
55
          // units: BG
56
          var actStart = iob.calcTotal(treatments, profile, lastDecayedBy, spec_profile).activity;
×
57
          var actEnd = iob.calcTotal(treatments, profile, cCalc.decayedBy, spec_profile).activity;
×
58
          var avgActivity = (actStart + actEnd) / 2;
×
59
          // units:  g     =       BG      *      scalar     /          BG / U                           *     g / U
60
          var delayedCarbs = ( avgActivity *  liverSensRatio / profile.getSensitivity(treatment.mills, spec_profile) ) * profile.getCarbRatio(treatment.mills, spec_profile);
×
61
          var delayMinutes = Math.round(delayedCarbs / profile.getCarbAbsorptionRate(treatment.mills, spec_profile) * 60);
×
62
          if (delayMinutes > 0) {
×
63
            cCalc.decayedBy.setMinutes(cCalc.decayedBy.getMinutes() + delayMinutes);
×
64
            decaysin_hr = (cCalc.decayedBy - time) / 1000 / 60 / 60;
×
65
          }
66
        }
67

68
        if (cCalc) {
×
69
          lastDecayedBy = cCalc.decayedBy;
×
70
        }
71

72
        if (decaysin_hr > 0) {
×
73
          //console.info('Adding ' + delayMinutes + ' minutes to decay of ' + treatment.carbs + 'g bolus at ' + treatment.mills);
74
          totalCOB += Math.min(Number(treatment.carbs), decaysin_hr * profile.getCarbAbsorptionRate(treatment.mills, spec_profile));
×
75
          //console.log("cob:", Math.min(cCalc.initialCarbs, decaysin_hr * profile.getCarbAbsorptionRate(treatment.mills)),cCalc.initialCarbs,decaysin_hr,profile.getCarbAbsorptionRate(treatment.mills));
76
          isDecaying = cCalc.isDecaying;
×
77
        } else {
78
          totalCOB = 0;
×
79
        }
80

81
      }
82
    });
83

84
    var rawCarbImpact = isDecaying * profile.getSensitivity(time, spec_profile) / profile.getCarbRatio(time, spec_profile) * profile.getCarbAbsorptionRate(time, spec_profile) / 60;
×
85
    var display = Math.round(totalCOB * 10) / 10;
×
86
    return {
×
87
      decayedBy: lastDecayedBy
88
      , isDecaying: isDecaying
89
      , carbs_hr: profile.getCarbAbsorptionRate(time, spec_profile)
90
      , rawCarbImpact: rawCarbImpact
91
      , cob: totalCOB
92
      , display: display
93
      , displayLine: 'COB: ' + display + 'g'
94
      , lastCarbs: lastCarbs
95
    };
96
  };
97

98
  cob.carbImpact = function carbImpact(rawCarbImpact, insulinImpact) {
23✔
99
    var liverSensRatio = 1.0;
×
100
    var liverCarbImpactMax = 0.7;
×
101
    var liverCarbImpact = Math.min(liverCarbImpactMax, liverSensRatio * insulinImpact);
×
102
    //var liverCarbImpact = liverSensRatio*insulinImpact;
103
    var netCarbImpact = Math.max(0, rawCarbImpact - liverCarbImpact);
×
104
    var totalImpact = netCarbImpact - insulinImpact;
×
105
    return {
×
106
      netCarbImpact: netCarbImpact,
107
      totalImpact: totalImpact
108
    };
109
  };
110

111
  cob.cobCalc = function cobCalc(treatment, profile, lastDecayedBy, time, spec_profile) {
23✔
112

113
    var delay = 20;
×
114
    var isDecaying = 0;
×
115
    var initialCarbs;
×
116

117
    if (treatment.carbs) {
×
118
      var carbTime = new Date(treatment.mills);
×
119
      
120
      var carbs_hr = profile.getCarbAbsorptionRate(treatment.mills, spec_profile);
×
121
      var carbs_min = carbs_hr / 60;
×
122

123
      var decayedBy = new Date(carbTime);
×
124
      var minutesleft = (lastDecayedBy - carbTime) / 1000 / 60;
×
125
      decayedBy.setMinutes(decayedBy.getMinutes() + Math.max(delay, minutesleft) + treatment.carbs / carbs_min);
×
126
      if (delay > minutesleft) {
×
127
        initialCarbs = parseInt(treatment.carbs);
×
128
      }
129
      else {
130
        initialCarbs = parseInt(treatment.carbs) + minutesleft * carbs_min;
×
131
      }
132
      var startDecay = new Date(carbTime);
×
133
      startDecay.setMinutes(carbTime.getMinutes() + delay);
×
134
      if (time < lastDecayedBy || time > startDecay) {
×
135
        isDecaying = 1;
×
136
      }
137
      else {
138
        isDecaying = 0;
×
139
      }
140
      return {
×
141
        initialCarbs: initialCarbs,
142
        decayedBy: decayedBy,
143
        isDecaying: isDecaying,
144
        carbTime: carbTime
145
      };
146
    }
147
    else {
148
      return '';
×
149
    }
150
  };
151

152
  cob.updateVisualisation = function updateVisualisation(sbx) {
23✔
153

154
    var prop = sbx.properties.cob;
×
155

156
    if (prop === undefined || prop.cob === undefined) { return; }
×
157

158
    var displayCob = Math.round(prop.cob * 10) / 10;
×
159

160
    var info = null;
×
161
    if (prop.lastCarbs) {
×
162
      var when = moment(prop.lastCarbs.mills).format('lll');
×
163
      var amount = prop.lastCarbs.carbs + 'g';
×
164
      info = [{label: 'Last Carbs', value: amount + ' @ ' + when }];
×
165
    }
166

167
    sbx.pluginBase.updatePillText(sbx, {
×
168
      value: displayCob + 'g'
169
      , label: 'COB'
170
      , info: info
171
    });
172
  };
173

174
  return cob;
23✔
175

176
}
177

178
module.exports = init;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2024 Coveralls, Inc