Sleep position tracking and OSCAR

Update: Torena now exports Somnopose-style CSV data right in the app. Yay!

I’m interested in tracking the position my body is in when I sleep: on my side or back. mostly. I’ve found a good solution for that for Android, the app Torena. You strap your phone to your chest with a runner’s belt, run the tracking app all night (30% of battery), and it produces nice little reports. It’s a good app, well designed, and worth the $10 if you need this kind of tracking. Somnopose is a similar app for iOS.

Pretty straightforward. But to make this really useful I want to pull the data in to OSCAR, the CPAP / sleep apnea tracking app that’s also recording all sorts of information about my breathing patterns, my blood oxygen, etc. I want to answer questions like “does sleeping on my back cause breathing problems?” and “do apnea events cause me to turn over, or does turning over cause apnea events?”. I succeeded! Code is in this gist.


I made the import via OSCAR’s Somnopose CSV support. The code linked above converts Torena’s JSON export to a format enough like Somnopose data that OSCAR would import it. It’s a bit of an impedence mismatch. Somnopose basically just records the phone’s rotational position in two axes, so it’s a data stream like “-89 -93 -92 -73 -23 4 2 1” with timestamps (that’d be rolling over from one side to stomach). Torena classifies the raw numeric data and exports categorized data, like “Left… Back… Right” with timestamps. So I just converted that back to numbers, albeit coarse ones. One extra trick is I had to add some extra CSV rows to mark the end of old positions so that OSCAR would draw square waves, not sawtooths.

Next steps

I did this convertor as a one-off just to see if it’d work. It does! To make this useful there’s three options:

  1. Turn my convertor into a nice reusable program
  2. Ask the Torena devs to export an OSCAR-compatible Somnopose CSV in the app
  3. Design a new input format for OSCAR along with the Torena dev

Option 2 is probably easiest, if the Torena dev is amenable. Option 3 would probably be better but requires some product design effort with the OSCAR team.

FWIW I think having the raw numeric data is probably more useful. You can measure partial positions that way. Also maybe infer movement activity from the magnitude of changes. But really the data display needs to be rethought: coding position as an angle from -180 to 180 is not intuitive. The classifying Torena does in-app makes sense here, but maybe it could be done in OSCAR instead.

Another specific problem to solve is time synchronization; Torena has its own clock independent of the CPAP machine and O2 sensor that OSCAR is getting data from. OSCAR doesn’t seem to have a good solution for that although you can at least input a manual offset for some things. It’s important to get it at least to the right minute, if not second.

See also the discussion on Apnea Board.