Last active
August 4, 2023 10:40
-
-
Save NelsonMinar/280646c46fac8739cfee9ae7c76f0496 to your computer and use it in GitHub Desktop.
Torena to Somnopose data convertor for OSCAR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Notes: | |
https://nelsonslog.wordpress.com/2021/07/21/sleep-position-tracking-and-oscar/ | |
http://www.apneaboard.com/forums/Thread-Torena-sleep-position-monitor-for-Android-similar-to-SomnoPose |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json, sys, csv | |
"""Quick and dirty convertor from Torena JSON export format to Somnapose CSV. | |
Written to get the data in to OSCAR. | |
A better solution would be to write a Torena importer for OSCAR. | |
Also it'd be nice if Torena exported raw orientation data like Somnapose does. | |
TODO: figure out some nice solution for the GotUp segments | |
References: | |
https://torena.koalative.com/ | |
http://www.proximalbox.com/somnopose/help/export.html | |
https://gitlab.com/pholy/OSCAR-code/-/blob/master/oscar/SleepLib/loader_plugins/somnopose_loader.cpp | |
""" | |
# Load the JSON data from the exported file | |
data = json.load(open('torena.export-2021-07-21-09-44-49.json')) | |
data = data[1] # file stores multiple sessions? Selecting one from my sample. | |
# Load the JSON data from Torena and strip out timestamps and positions. | |
# { "position": "Right", "positionEndTimestamp": 1626873212, "positionStartTimestamp": 1626873071 } | |
rows = [] | |
for p in data['positions']: | |
rows.append((p['positionStartTimestamp'], p['positionEndTimestamp'], p['position'])) | |
rows.sort() # probably unnecessary | |
# Convert the timestamps and positions to Somnapose-style data | |
# Timestamp,Orientation,Inclination,Time_of_day,Date | |
# 329027345.46,114.47,80.18,23:29:05 | |
position_to_orientation = { 'Back': '180', 'Left': '-90', 'Right': '90', 'Stomach': '0', 'GotUp': '0' } | |
last_orientation = None | |
last_inclination = None | |
csvdata = [] | |
for r in rows: | |
ios_timestamp = r[0] - 978307200 # convert Unix epoch to iOS epoch | |
orientation = position_to_orientation[r[2]] | |
inclination = '90' | |
if r[2] == 'GotUp': | |
inclination = '0' | |
# Write an end event for the old position so the graph looks like square waves, not sawtooth. | |
if last_orientation is not None and last_inclination is not None: | |
csvdata.append((ios_timestamp, last_orientation, last_inclination)) | |
csvdata.append((ios_timestamp, orientation, inclination)) | |
last_orientation = orientation | |
last_inclination = inclination | |
# And print out the CSV | |
# Skip the redundant Time_of_day and Date columns; OSCAR ignores them anyway. | |
writer = csv.writer(sys.stdout, lineterminator='\n') | |
writer.writerow(('Timestamp','Orientation','Inclination')) | |
writer.writerows(csvdata) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Timestamp | Orientation | Inclination | |
---|---|---|---|
648536914 | 0 | 90 | |
648536919 | 0 | 90 | |
648536919 | 0 | 0 | |
648536934 | 0 | 0 | |
648536934 | 0 | 90 | |
648536939 | 0 | 90 | |
648536939 | 0 | 0 | |
648536944 | 0 | 0 | |
648536944 | 0 | 90 | |
648536964 | 0 | 90 | |
648536964 | 0 | 0 | |
648536974 | 0 | 0 | |
648536974 | -90 | 90 | |
648537295 | -90 | 90 | |
648537295 | 180 | 90 | |
648537330 | 180 | 90 | |
648537330 | -90 | 90 | |
648537791 | -90 | 90 | |
648537791 | 180 | 90 | |
648537871 | 180 | 90 | |
648537871 | -90 | 90 | |
648542806 | -90 | 90 | |
648542806 | 180 | 90 | |
648543112 | 180 | 90 | |
648543112 | 90 | 90 | |
648547850 | 90 | 90 | |
648547850 | 180 | 90 | |
648549264 | 180 | 90 | |
648549264 | 90 | 90 | |
648553545 | 90 | 90 | |
648553545 | 180 | 90 | |
648554939 | 180 | 90 | |
648554939 | 90 | 90 | |
648558495 | 90 | 90 | |
648558495 | 0 | 0 | |
648558686 | 0 | 0 | |
648558686 | 180 | 90 | |
648558706 | 180 | 90 | |
648558706 | 0 | 0 | |
648558711 | 0 | 0 | |
648558711 | 180 | 90 | |
648558726 | 180 | 90 | |
648558726 | 0 | 0 | |
648558731 | 0 | 0 | |
648558731 | 90 | 90 | |
648560489 | 90 | 90 | |
648560489 | 180 | 90 | |
648560527 | 180 | 90 | |
648560527 | -90 | 90 | |
648563600 | -90 | 90 | |
648563600 | 180 | 90 | |
648565871 | 180 | 90 | |
648565871 | 90 | 90 | |
648566012 | 90 | 90 | |
648566012 | 0 | 0 | |
648566082 | 0 | 0 | |
648566082 | 180 | 90 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[{"alarmDelay":0,"alarmEnabled":false,"alarmPosition":"Back","alarmRingtone":"None","alarmVibration":"None","degreesBackFrom":40,"degreesBackTo":125,"degreesGotUpFrom":40,"degreesLeftFrom":-40,"degreesLeftTo":40,"degreesRightFrom":125,"degreesRightTo":-125,"degreesStomachFrom":-125,"degreesStomachTo":-40,"positions":[{"position":"Stomach","positionEndTimestamp":1626814371,"positionStartTimestamp":1626814366},{"position":"Right","positionEndTimestamp":1626814381,"positionStartTimestamp":1626814371},{"position":"Back","positionEndTimestamp":1626814391,"positionStartTimestamp":1626814381},{"position":"Left","positionEndTimestamp":1626814401,"positionStartTimestamp":1626814391},{"position":"Back","positionEndTimestamp":1626814406,"positionStartTimestamp":1626814401},{"position":"Left","positionEndTimestamp":1626814662,"positionStartTimestamp":1626814406},{"position":"Right","positionEndTimestamp":1626815708,"positionStartTimestamp":1626814662},{"position":"Back","positionEndTimestamp":1626815713,"positionStartTimestamp":1626815708},{"position":"Left","positionEndTimestamp":1626815858,"positionStartTimestamp":1626815713},{"position":"Back","positionEndTimestamp":1626816008,"positionStartTimestamp":1626815858},{"position":"Right","positionEndTimestamp":1626816012,"positionStartTimestamp":1626816008}],"screenFacing":"Up","screenRotation":"LandscapeTopLeft","sessionEndTimestamp":1626816012,"sessionId":1,"sessionStartTimestamp":1626814366,"trackingDelay":0},{"alarmDelay":0,"alarmEnabled":false,"alarmPosition":"Back","alarmRingtone":"None","alarmVibration":"None","degreesBackFrom":40,"degreesBackTo":125,"degreesGotUpFrom":40,"degreesLeftFrom":-40,"degreesLeftTo":40,"degreesRightFrom":125,"degreesRightTo":-125,"degreesStomachFrom":-125,"degreesStomachTo":-40,"positions":[{"position":"Stomach","positionEndTimestamp":1626844119,"positionStartTimestamp":1626844114},{"position":"GotUp","positionEndTimestamp":1626844134,"positionStartTimestamp":1626844119},{"position":"Stomach","positionEndTimestamp":1626844139,"positionStartTimestamp":1626844134},{"position":"GotUp","positionEndTimestamp":1626844144,"positionStartTimestamp":1626844139},{"position":"Stomach","positionEndTimestamp":1626844164,"positionStartTimestamp":1626844144},{"position":"GotUp","positionEndTimestamp":1626844174,"positionStartTimestamp":1626844164},{"position":"Left","positionEndTimestamp":1626844495,"positionStartTimestamp":1626844174},{"position":"Back","positionEndTimestamp":1626844530,"positionStartTimestamp":1626844495},{"position":"Left","positionEndTimestamp":1626844991,"positionStartTimestamp":1626844530},{"position":"Back","positionEndTimestamp":1626845071,"positionStartTimestamp":1626844991},{"position":"Left","positionEndTimestamp":1626850006,"positionStartTimestamp":1626845071},{"position":"Back","positionEndTimestamp":1626850312,"positionStartTimestamp":1626850006},{"position":"Right","positionEndTimestamp":1626855050,"positionStartTimestamp":1626850312},{"position":"Back","positionEndTimestamp":1626856464,"positionStartTimestamp":1626855050},{"position":"Right","positionEndTimestamp":1626860745,"positionStartTimestamp":1626856464},{"position":"Back","positionEndTimestamp":1626862139,"positionStartTimestamp":1626860745},{"position":"Right","positionEndTimestamp":1626865695,"positionStartTimestamp":1626862139},{"position":"GotUp","positionEndTimestamp":1626865886,"positionStartTimestamp":1626865695},{"position":"Back","positionEndTimestamp":1626865906,"positionStartTimestamp":1626865886},{"position":"GotUp","positionEndTimestamp":1626865911,"positionStartTimestamp":1626865906},{"position":"Back","positionEndTimestamp":1626865926,"positionStartTimestamp":1626865911},{"position":"GotUp","positionEndTimestamp":1626865931,"positionStartTimestamp":1626865926},{"position":"Right","positionEndTimestamp":1626867689,"positionStartTimestamp":1626865931},{"position":"Back","positionEndTimestamp":1626867727,"positionStartTimestamp":1626867689},{"position":"Left","positionEndTimestamp":1626870800,"positionStartTimestamp":1626867727},{"position":"Back","positionEndTimestamp":1626873071,"positionStartTimestamp":1626870800},{"position":"Right","positionEndTimestamp":1626873212,"positionStartTimestamp":1626873071},{"position":"GotUp","positionEndTimestamp":1626873282,"positionStartTimestamp":1626873212},{"position":"Back","positionEndTimestamp":1626873288,"positionStartTimestamp":1626873282}],"screenFacing":"Up","screenRotation":"LandscapeTopLeft","sessionEndTimestamp":1626873288,"sessionId":2,"sessionStartTimestamp":1626844114,"trackingDelay":0}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment