<commit_before>'use strict';

var _ = require('lodash');
var moment = require('moment');
var times = require('../times');
var levels = require('../levels');

function init(ctx) {
  var utils = require('../utils')(ctx);

  var sensorState = {
    name: 'xdrip-js'
    , label: 'Sensor Status'
    , pluginType: 'pill-status'
  };

  sensorState.getPrefs = function getPrefs(sbx) {
    return {
      enableAlerts: sbx.extendedSettings.enableAlerts || false
    };
  };

  sensorState.setProperties = function setProperties (sbx) {
    sbx.offerProperty('sensorState', function setProp ( ) {
      return sensorState.getStateString(sbx);
    });
  };

  sensorState.checkNotifications = function checkNotifications(sbx) {

    var info = sbx.properties.sensorState;

    if (info && info.notification) {
      var notification = _.extend({}, info.notification, {
        plugin: sensorState
        , debug: {
          stateString: sensorInfo.stateString
        }
      });

      sbx.notifications.requestNotify(notification);
    }

  };

  sensorState.getStateString = function findLatestState(sbx) {
    var prefs = sensorState.getPrefs(sbx);

    var recentHours = 24; 
    var recentMills = sbx.time - times.hours(recentHours).msecs;

    var result = {
      seenDevices: { }
      , latest: null
      , lastDevice: null
      , lastState: null
      , lastStateString: null
      , lastStateStringShort: null
      , lastStateTime: null
      , lastVoltageA: null
      , lastVoltageB: null
      , lastRuntime: null
      , lastTemperature: null
      , lastResistance: null
      , lastTxState: null
      , lastTxStateString: null
    };

    function toMoments (status) {
      return {
        when:  moment(status.mills)
        , timestamp: status.xdripjs && status.xdripjs.timestamp && moment(status.xdripjs.timestamp)
      };
    }

    function getDevice(status) {
      var uri = status.device || 'device';
      var device = result.seenDevices[uri];

      if (!device) {
        device = {
          name: utils.deviceName(uri)
          , uri: uri
        };

        result.seenDevices[uri] = device;
      }
      return device;
    }

    var recentData = _.chain(sbx.data.devicestatus)
      .filter(function (status) {
        return ('xdripjs' in status) && sbx.entryMills(status) <= sbx.time && sbx.entryMills(status) >= recentMills;
      })
      .value( );

    recentData = _.sortBy(recentData, 'xdripjs.timestamp');

    _.forEach(recentData, function eachStatus (status) {
      getDevice(status);

      var moments = toMoments(status);

      if (status.xdripjs && (!result.latest || moments.timestamp && moments.timestamp.isAfter(result.lastStateTime))) {
        result.latest = status;
        result.lastStateTime = moment(status.xdripjs.timestamp);
      }
    });

    var sendNotification = false;
    var sound = 'incoming';
    var message;

    var sensorInfo = result.latest;

    result.level = levels.NONE;

    if (sensorInfo && sensorInfo.xdripjs) {

      if (sensorInfo.xdripjs.state != 0x6) {
        // TODO: determine whether to send a notification
        sendNotification = true;
        message = 'Sensor state: ' + sensorInfo.xdripjs.stateString;
        result.level = levels.WARN;
      }

      //allow for 20 minute period after a full hour during which we'll alert the user
      if (prefs.enableAlerts && sendNotification) {
        result.notification = {
          title: 'Sensor State: ' + sensorInfo.xdripjs.stateString
          , message: message
          , pushoverSound: sound
          , level: result.level
          , group: 'xDrip-js'
        };
      }

      result.lastState = sensorInfo.xdripjs.state;
      result.lastStateString = sensorInfo.xdripjs.stateString;
      result.lastStateStringShort = sensorInfo.xdripjs.stateStringShort;
      result.lastVoltageA = sensorInfo.xdripjs.voltagea;
      result.lastVoltageB = sensorInfo.xdripjs.voltageb;
      result.lastRuntime = sensorInfo.xdripjs.runtime;
      result.lastTemperature = sensorInfo.xdripjs.temperature;
      result.lastResistance = sensorInfo.xdripjs.resistance;
      result.lastTxState = sensorInfo.xdripjs.txState;
      result.lastTxStateString = sensorInfo.xdripjs.txStateString;
    }

    return result;
  };

  sensorState.updateVisualisation = function updateVisualisation (sbx) {

    var sensor = sbx.properties.sensorState;
    var info = [];

    _.forIn(sensor.seenDevices, function seenDevice (device) {
      info.push( { label: 'Seen: ', value: device.name } );
    });

    info.push( { label: 'Status: ', value: (sensor && sensor.lastStateString) || 'Unknown' } );
    info.push( { label: 'State Time: ', value: (sensor && sensor.lastStateTime && sensor.lastStateTime.format()) || 'Unknown' } );

    if (sensor && sensor.lastVoltageA) {
      info.push( { label: 'VoltageA: ', value: sensor.lastVoltageA } );
    }

    if (sensor && sensor.lastVoltageB) {
      info.push( { label: 'VoltageB: ', value: sensor.lastVoltageB } );
    }

    if (sensor && sensor.lastRuntime) {
      info.push( { label: 'Runtime: ', value: sensor.lastRunTime } );
    }

    if (sensor && sensor.lastTemperature) {
      info.push( { label: 'Temperature: ', value: sensor.lastTemperature } );
    }

    if (sensor && sensor.lastResistance) {
      info.push( { label: 'Resistance: ', value: sensor.lastResistance } );
    }

    if (sensor && sensor.lastTxStateString) {
      info.push( { label: 'Txmitter State: ', value: sensor.lastTxStateString } );
    }

    if (sensor) {
      var statusClass = null;
      if (sensor.level === levels.URGENT) {
          statusClass = 'urgent';
      } else if (sensor.level === levels.WARN) {
        statusClass = 'warn';
      }

      sbx.pluginBase.updatePillText(sensorState, {
        value: (sensor && sensor.lastStateStringShort) || (sensor && sensor.lastStateString) || 'Unknown'
        , label: 'CGM'
        , info: info
        , pillClass: statusClass
      });
    }
  };

  return sensorState;
}

module.exports = init;

<commit_msg>Added many additional xdrip-js fields.<commit_after>'use strict';

var _ = require('lodash');
var moment = require('moment');
var times = require('../times');
var levels = require('../levels');

function init(ctx) {
  var utils = require('../utils')(ctx);

  var sensorState = {
    name: 'xdrip-js'
    , label: 'Sensor Status'
    , pluginType: 'pill-status'
  };

  sensorState.getPrefs = function getPrefs(sbx) {
    return {
      enableAlerts: sbx.extendedSettings.enableAlerts || false
    };
  };

  sensorState.setProperties = function setProperties (sbx) {
    sbx.offerProperty('sensorState', function setProp ( ) {
      return sensorState.getStateString(sbx);
    });
  };

  sensorState.checkNotifications = function checkNotifications(sbx) {

    var info = sbx.properties.sensorState;

    if (info && info.notification) {
      var notification = _.extend({}, info.notification, {
        plugin: sensorState
        , debug: {
          stateString: info.lastStateString
        }
      });

      sbx.notifications.requestNotify(notification);
    }

  };

  sensorState.getStateString = function findLatestState(sbx) {
    var prefs = sensorState.getPrefs(sbx);

    var recentHours = 24; 
    var recentMills = sbx.time - times.hours(recentHours).msecs;

    var result = {
      seenDevices: { }
      , latest: null
      , lastDevice: null
      , lastState: null
      , lastStateString: null
      , lastStateStringShort: null
      , lastStateTime: null
      , lastTxId: null
      , lastTxStatus: null
      , lastTxStatusString: null
      , lastTxStatusStringShort: null
      , lastTxActivation: null
      , lastMode: null
      , lastRssi: null
      , lastUnfiltered: null
      , lastFiltered: null
      , lastNoise: null
      , lastNoiseString: null
      , lastSlope: null
      , lastIntercept: null
      , lastCalType: null
      , lastCalibrationDate: null
      , lastBatteryTimestamp: null
      , lastVoltageA: null
      , lastVoltageB: null
      , lastTemperature: null
      , lastResistance: null
    };

    function toMoments (status) {
      return {
        when:  moment(status.mills)
        , timestamp: status.xdripjs && status.xdripjs.timestamp && moment(status.xdripjs.timestamp)
      };
    }

    function getDevice(status) {
      var uri = status.device || 'device';
      var device = result.seenDevices[uri];

      if (!device) {
        device = {
          name: utils.deviceName(uri)
          , uri: uri
        };

        result.seenDevices[uri] = device;
      }
      return device;
    }

    var recentData = _.chain(sbx.data.devicestatus)
      .filter(function (status) {
        return ('xdripjs' in status) && sbx.entryMills(status) <= sbx.time && sbx.entryMills(status) >= recentMills;
      })
      .value( );

    recentData = _.sortBy(recentData, 'xdripjs.timestamp');

    _.forEach(recentData, function eachStatus (status) {
      getDevice(status);

      var moments = toMoments(status);

      if (status.xdripjs && (!result.latest || moments.timestamp && moments.timestamp.isAfter(result.lastStateTime))) {
        result.latest = status;
        result.lastStateTime = moment(status.xdripjs.timestamp);
      }
    });

    var sendNotification = false;
    var sound = 'incoming';
    var message;

    var sensorInfo = result.latest;

    result.level = levels.NONE;

    if (sensorInfo && sensorInfo.xdripjs) {

      if (sensorInfo.xdripjs.state != 0x6) {
        // TODO: determine whether to send a notification
        sendNotification = true;
        message = 'Sensor state: ' + sensorInfo.xdripjs.stateString;
        result.level = levels.WARN;
      }

      //allow for 20 minute period after a full hour during which we'll alert the user
      if (prefs.enableAlerts && sendNotification) {
        result.notification = {
          title: 'Sensor State: ' + sensorInfo.xdripjs.stateString
          , message: message
          , pushoverSound: sound
          , level: result.level
          , group: 'xDrip-js'
        };
      }

      result.lastState = sensorInfo.xdripjs.state;
      result.lastStateString = sensorInfo.xdripjs.stateString;
      result.lastStateStringShort = sensorInfo.xdripjs.stateStringShort;
      result.lastTxId = sensorInfo.xdripjs.txId;
      result.lastTxStatus = sensorInfo.xdripjs.txStatus;
      result.lastTxStatusString = sensorInfo.xdripjs.txStatusString;
      result.lastTxStatusStringShort = sensorInfo.xdripjs.txStatusStringShort;
      result.lastTxActivation = sensorInfo.xdripjs.txActivation;
      result.lastMode = sensorInfo.xdripjs.mode;
      result.lastRssi = sensorInfo.xdripjs.rssi;
      result.lastUnfiltered = sensorInfo.xdripjs.unfiltered;
      result.lastFiltered = sensorInfo.xdripjs.filtered;
      result.lastNoise = sensorInfo.xdripjs.noise;
      result.lastNoiseString = sensorInfo.xdripjs.noiseString;
      result.lastSlope = sensorInfo.xdripjs.slope;
      result.lastIntercept = sensorInfo.xdripjs.intercept;
      result.lastCalType = sensorInfo.xdripjs.calType;
      result.lastCalibrationDate = sensorInfo.xdripjs.lastCalibrationDate;
      result.lastBatteryTimestamp = sensorInfo.xdripjs.batteryTimestamp;
      result.lastVoltageA = sensorInfo.xdripjs.voltagea;
      result.lastVoltageB = sensorInfo.xdripjs.voltageb;
      result.lastTemperature = sensorInfo.xdripjs.temperature;
      result.lastResistance = sensorInfo.xdripjs.resistance;
    }

    return result;
  };

  sensorState.updateVisualisation = function updateVisualisation (sbx) {

    var sensor = sbx.properties.sensorState;
    var info = [];

    _.forIn(sensor.seenDevices, function seenDevice (device) {
      info.push( { label: 'Seen: ', value: device.name } );
    });

    info.push( { label: 'State Time: ', value: (sensor && sensor.lastStateTime && sensor.lastStateTime.diff(moment(), 'minutes') + ' minutes ago') || 'Unknown' } );
    info.push( { label: 'Mode: ', value: (sensor && sensor.lastMode) || 'Unknown' } );
    info.push( { label: 'Status: ', value: (sensor && sensor.lastStateString) || 'Unknown' } );
    info.push( { label: 'Tx ID: ', value: (sensor && sensor.lastTxId) || 'Unknown' } );
    info.push( { label: 'Tx Status: ', value: (sensor && sensor.lastTxStatusString) || 'Unknown' } );

    if (sensor) {
      if (sensor.lastTxActivation) {
        info.push( { label: 'Tx Age: ', value: moment(sensor.lastTxActivation).diff(moment(), 'days') + ' days ago' } );
      }

      if (sensor.lastRssi) {
        info.push( { label: 'RSSI: ', value: sensor.lastRssi } );
      }

      if (sensor.lastUnfiltered) {
        info.push( { label: 'Unfiltered: ', value: sensor.lastUnfiltered } );
      }

      if (sensor.lastFiltered) {
        info.push( { label: 'Filtered: ', value: sensor.lastFiltered } );
      }

      if (sensor.lastSlope) {
        info.push( { label: 'Slope: ', value: sensor.lastSlope } );
      }

      if (sensor.lastIntercept) {
        info.push( { label: 'Intercept: ', value: sensor.lastIntercept } );
      }

      if (sensor.lastCalType) {
        info.push( { label: 'CalType: ', value: sensor.lastCalType } );
      }

      if (sensor.lastCalibrationDate) {
        info.push( { label: 'Calibration: ', value: moment(sensor.lastCalibrationDate).diff(moment(), 'hours') + ' hours ago' } );
      }

      if (sensor.lastNoiseString) {
        info.push( { label: 'Noise: ', value: sensor.lastNoiseString } );
      }

      if (sensor.lastBatteryTimestamp) {
        info.push( { label: 'Battery: ', value: moment(sensor.lastBatteryTimestamp).diff(moment(), 'minutes') + ' minutes ago' } );
      }

      if (sensor.lastVoltageA) {
        info.push( { label: 'VoltageA: ', value: sensor.lastVoltageA } );
      }

      if (sensor.lastVoltageB) {
        info.push( { label: 'VoltageB: ', value: sensor.lastVoltageB } );
      }

      if (sensor.lastTemperature) {
        info.push( { label: 'Temperature: ', value: sensor.lastTemperature } );
      }

      if (sensor.lastResistance) {
        info.push( { label: 'Resistance: ', value: sensor.lastResistance } );
      }

      var statusClass = null;
      if (sensor.level === levels.URGENT) {
          statusClass = 'urgent';
      } else if (sensor.level === levels.WARN) {
        statusClass = 'warn';
      }

      sbx.pluginBase.updatePillText(sensorState, {
        value: (sensor && sensor.lastStateStringShort) || (sensor && sensor.lastStateString) || 'Unknown'
        , label: 'CGM'
        , info: info
        , pillClass: statusClass
      });
    }
  };

  return sensorState;
}

module.exports = init;


{'fraction_non_alphanumeric': 0.12691152375750955, 'fraction_numerical': 0.0008192244675040961, 'mean_word_length': 2.654940119760479, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5594944', 'n_tokens_mistral': 4591, 'n_tokens_neox': 4454, 'n_words': 883}