BangleApps/apps/sleeplog
storm64 b8721fbdcf sleeplog: New power saving mode using build in movement detection
* New power saving mode using build in movement detection
Update app.js
 - add displaying powersaving status
Update boot.js
 - add power save mode
 - minimize fix #1425 to issue #1423
 - minimize wake/sleep decision
 - add checking for correct this reference
 - add checking for global object existence
 - remove unneeded global. prefix
Update lib.js
 - add powersaving setting to setEnabled()
 - fix missing logfile issue #1423 on all functions
 - remove check for changes in setEnabled(...) to always restart the service
Update settings.js
 - add settings powersaving and maxmove
 - add displaying settings depending on power saving mode
 - restart service when changing enabled, logfile and powersaving
2022-02-12 01:43:58 +01:00
..
ChangeLog Update ChangeLog 2022-02-11 13:45:01 +01:00
README.md sleeplog: Add Sleep Log App 2022-02-11 09:29:02 +01:00
app-icon.js sleeplog: Add Sleep Log App 2022-02-11 09:29:02 +01:00
app.js sleeplog: New power saving mode using build in movement detection 2022-02-12 01:43:58 +01:00
app.png sleeplog: Add Sleep Log App 2022-02-11 09:29:02 +01:00
boot.js sleeplog: New power saving mode using build in movement detection 2022-02-12 01:43:58 +01:00
lib.js sleeplog: New power saving mode using build in movement detection 2022-02-12 01:43:58 +01:00
metadata.json Update metadata.json 2022-02-11 13:45:10 +01:00
screenshot1.png sleeplog: Add Sleep Log App 2022-02-11 09:29:02 +01:00
screenshot2.png sleeplog: Add Sleep Log App 2022-02-11 09:29:02 +01:00
screenshot3.png sleeplog: Add Sleep Log App 2022-02-11 09:29:02 +01:00
settings.js sleeplog: New power saving mode using build in movement detection 2022-02-12 01:43:58 +01:00

README.md

Sleep Log

This app logs and displays the four following states:
unknown, not worn, awake, sleeping
It derived from the SleepPhaseAlarm and uses the accelerometer to estimate sleep and wake states with the principle of Estimation of Stationary Sleep-segments (ESS) and the internal temperature to decide sleeping or not worn when the watch is resting.

Operating Principle

  • ESS calculation
    The accelerometer polls values with 12.5Hz. On each poll the magnitude value is saved. When 13 values are collected, every 1.04 seconds, the standard deviation over this values is calculated.
    Is the calculated standard deviation lower than the "no movement" threshold (NoMoThresh) a "no movement" counter is incremented. Each time the "no movement" threshold is reached the "no movement" counter will be reset.
    When the "no movement" counter reaches the sleep threshold the watch is considered as resting. (The sleep threshold is calculated from the MinDuration setting, Example: sleep threshold = MinDuration * 60 / calculation interval => 10min * 60s/min / 1.04s ~= 576,9 rounded up to 577)
    To check if a resting watch indicates as sleeping, the internal temperature must be greater than the temperature threshold (TempThresh). Otherwise the watch is considered as not worn.
  • True Sleep
    The true sleep value is a simple addition of all registert sleeping periods.
  • Consecutive Sleep
    In addition the consecutive sleep value tries to predict the complete time you were asleep, even the light sleeping phases with registered movements. All periods after a sleeping period will be summarized til the first following non sleeping period that is longer then the maximal awake duration (MaxAwake). If this sum is lower than the minimal consecutive sleep duration (MinConsec) it is not considered, otherwise it will be added to the consecutive sleep value.
  • Logging
    To minimize the log size only a changed state is logged.

Control


  • Swipe
    Swipe left/right to display the previous/following day.
  • Touch / BTN
    Touch the screen to open the settings menu to exit or change settings.

Settings


  • BreakTod break at time of day
    0 / 1 / ... / 10 / ... / 12
    Change time of day on wich the lower graph starts and the upper graph ends.
  • MaxAwake maximal awake duration
    15min / 20min / ... / 60min / ... / 120min
    Adjust the maximal awake duration upon the exceeding of which aborts the consecutive sleep period.
  • MinConsec minimal consecutive sleep duration
    15min / 20min / ... / 30min / ... / 120min
    Adjust the minimal consecutive sleep duration that will be considered for the consecutive sleep value.
  • TempThresh temperature threshold
    20°C / 20.5°C / ... / 25°C / ... / 40°C
    The internal temperature must be greater than this threshold to log sleeping, otherwise it is not worn.
  • NoMoThresh no movement threshold
    0.006 / 0.007 / ... / 0.012 / ... / 0.020
    The standard deviation over the measured values needs to be lower then this threshold to count as not moving.
    The defaut threshold value worked best for my watch. A threshold value below 0.008 may get triggert by noise.
  • MinDuration minimal no movement duration
    5min / 6min / ... / 10min / ... / 15min
    If no movement is detected for this duration, the watch is considered as resting.
  • Enabled
    on / off
    En-/Disable the service (all background activities). Saves battery, but might make this app useless.
  • Logfile
    default / off
    En-/Disable logging by setting the logfile to sleeplog.log / undefined.
    If the logfile has been customized it is displayed with custom.

Global Object and Module Functions


For easy access from the console or other apps the following parameters, values and functions are noteworthy:

>global.sleeplog
={
  enabled: true,                // bool   / service status indicator
  logfile: "sleeplog.log",      // string / used logfile
  resting: false,               // bool   / indicates if the watch is resting
  status: 2,                    // int    / actual status: 0 = unknown, 1 = not worn, 2 = awake, 3 = sleeping
  firstnomodate: 1644435877595, // number / Date.now() from first recognised no movement
  stop: function () { ... },    // funct  / stops the service until the next load()
  start: function () { ... },   // funct  / restarts the service
  ...
 }

>require("sleeplog")
={
  setEnabled: function (enable, logfile) { ... },
    // en-/disable the service and/or logging
    // * enable  / bool / service status to change to
    // * logfile / bool or string
    //   - true            = enables logging to "sleeplog.log"
    //   - "some_file.log" = enables logging to "some_file.log"
    //   - false           = disables logging
    // returns: bool or undefined
    // - true      = changes executed
    // - false     = no changes needed
    // - undefined = no global.sleeplog found
  readLog: function (since, until) { ... },
    // read the raw log data for a specific time period
    // * since / Date or number / startpoint of period
    // * until / Date or number / endpoint of period
    // returns: array
    // * [[number, int, string], [...], ... ] / sorting: latest first
    //   - number // timestamp in ms
    //   - int    // status: 0 = unknown, 1 = not worn, 2 = awake, 3 = sleeping
    //   - string // additional information
    // * [] = no data available or global.sleeplog found
  getReadableLog: function (printLog, since, until) { ... }
    // read the log data as humanreadable string for a specific time period
    // * since / Date or number / startpoint of period
    // * until / Date or number / endpoint of period
    // returns: string
    // * "{substring of ISO date} - {status} for {duration}min\n...", sorting: latest last
    // * undefined = no data available or global.sleeplog found
  restoreLog: function (logfile) { ... }
    // eliminate some errors inside a specific logfile
    // * logfile / string / name of the logfile that will be restored
    // returns: int / number of changes that were made
  reinterpretTemp: function (logfile, tempthresh) { ... }
    // reinterpret worn status based on given temperature threshold
    // * logfile    / string / name of the logfile
    // * tempthresh / float  / new temperature threshold
    // returns: int / number of changes that were made
 }

Worth Mentioning


To do list

  • Send the logged information to Gadgetbridge. (For now I have no idea how to achieve this, help is appreciated.)
  • Calculate and display overall sleep statistics.

Requests, Bugs and Feedback

Please leave requests and bug reports by raising an issue at github.com/storm64/BangleApps or send me a mail.

Creator

Storm64 (Mail, github)

Contributors

nxdefiant (github)

Attributions

License

MIT License