Goodnight Zeo

I love quantifiable data and had been using the Zeo Mobile sleep monitor to track sleep quality.  I had worked on some projects of my own to use this data too.  After I finished the most basic functionality for these projects I lost interest, but planned to come back to them eventually. Unfortunately, my Zeo hardware started having more and more trouble and eventually I stopped using it. I still really enjoyed the concept and thought I would come back eventually.

At some point later I checked back and found they had gone out of business! More frustrating, that meant all the sleep data I had on their systems was gone. I had since removed the app thus removing local data, so the only bit of data I still had was the CSV file I exported during development.  This ended up being about 2 months out of at least 7 that I tracked.  I can at least say that I feel like it helped me improve my sleep. which is the real value.  Fun data is just a bonus.

However this does seal the deal that I will not come back to these projects.  I decided I should release what I have in case it benefits the people out there who still have function Zeo products.  I’m actually surprised that I haven’t been able to find anything out there really built on their Android API.  Most of the projects I could find seem to be centered around the Zeo Bedside unit because in some ways it gives you access to more data.

My projects contained two components which work with Zeo sleep data.  One is a reimplmentation of the SmartWake adaptive alarm feature for Android.  SmarkWake was the feature that was supposed to wake you at the optimum time such as when you are entering or leaving REM sleep.  i never saw the feature work, so I built my own.  The other is PHP code to display CSV sleep data in progress graph form.

Source and more detail available at the GitHub repository.

Other relevant information to using the Zeo Android API was mentioned in an older post:
Using the Zeo Android API

ALSO:
One of the prominent places Zeo was talked about was at the Quantified Self forums, so I mentioned this code in the Zeo shutdown thread in case anyone finds a use for it:
Zeo shutting down: export your data!

Using the Zeo Android API

https://github.com/zeoeng/zeo-android-api

There are a bunch of things that are not obvious from the documentation.  These are just notes on things I figured out while developing an app using their API.

To clarify terminology I’m using:

  • Short epoch – 30 seconds worth of sleep data.  The base hypnogram contains sleep stages that each represent a short epoch.
  • Long epoch – 5 minutes worth of sleep data which Zeo summarizes as one sleep stage regardless of the stages of the corresponding short epochs.  The display hypnogram contains sleep stages that each represent a long epoch.

 

  1. Though the base hypnogram contains a reading every 30 seconds, the headband only transmits these back to the phone every 5 minutes.  I’ve seen it transmit in smaller increments but I think this only happens upon certain events:
    1. Headband is docked/undocked
    2. Headband is on/off head
    3. Personally I’ve never seen SmartWake work, but I wouldn’t be surprised if the headband knew to transmit an update any time you move in and out of REM.  I haven’t actually seen this, but it just sounds like a reasonable possibility.
  2. The display hypnogram seems to always contain an even number of epochs.  So when there is only one long epoch of real data the display hypnogram will contain two elements, the second being a 0 for “undefined”.  When the next long epoch finishes, the second element will be updated with real data and the display hypnogram will still have two elements.
    1. This means if you want to know the most recent long epoch stage you cannot just take the last element.
  3. When a Sleep Record is “finalized” it has appeared that the undefined epochs get trimmed from the end of the display hypnogram but not the base hypnogram.  After a particular night of sleep I saw that the Sleep Record had continued to be updated long after I docked the headband (both hypnograms).  Eventually it did stop, and at that point the undefined epochs were removed from the end of the display hypnogram.  The same did not happen to the base hypnogram
  4. When a smaller increment of short epochs is transmitted as described in #1, it does not write a corresponding incomplete long epoch at that point.  The long epoch will be added to the display hypnogram when it is finished.