Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

* Move installation to Makefile from debian specific way

* Read settings using classes
* Fix backup creation
* Found time zone data
* Read extra chunk to bring watch to charge mode only upon extraction
* Fix data for overnight runs as only time being reported for points
  • Loading branch information...
commit 44df77b960ca692a5dcd219a4e2b46009b8e49ee 1 parent be4b192
@mlt authored
View
48 Makefile
@@ -0,0 +1,48 @@
+DESTDIR=/usr
+
+.PHONY: all ui install
+
+all: ui
+
+ui:
+ $(MAKE) -C src
+
+CORE=commands.py \
+device.py \
+__init__.py \
+progress_gtk.py \
+progress.glade \
+progress_qt.py \
+ui_progress.py \
+progress_text.py \
+reader_cresta.py \
+reader.py \
+reader_schwinn.py \
+utils.py \
+writer_csv.py
+
+EXTRA=__init__.py \
+writer_sqlite.py
+
+SRC=csv2tcx.py \
+download.py \
+settings.py
+
+install:
+ mkdir -p $(DESTDIR)/share/schwinn810
+ install -m 0755 $(addprefix src/, $(SRC)) $(DESTDIR)/share/schwinn810/
+
+ mkdir -p $(DESTDIR)/share/schwinn810/core
+ install -m 0644 $(addprefix src/core/, $(CORE)) $(DESTDIR)/share/schwinn810/core/
+
+ mkdir -p $(DESTDIR)/share/schwinn810/extra
+ install -m 0644 $(addprefix src/extra/, $(EXTRA)) $(DESTDIR)/share/schwinn810/extra/
+
+ mkdir -p $(DESTDIR)/share/schwinn810/web
+ install -m 0644 src/web/mmf.py src/web/tcx2web.py $(DESTDIR)/share/schwinn810/web/
+
+ mkdir -p $(DESTDIR)/share/schwinn810/web/antd
+ install -m 0644 src/web/antd/*.py src/web/antd/LICENSE $(DESTDIR)/share/schwinn810/web/antd/
+
+ install -m 0755 linux/schwinn810 $(DESTDIR)/bin/
+ install -m 0755 linux/babelize.sh linux/schwinn810-tray.py $(DESTDIR)/share/schwinn810/
View
24 debian/install
@@ -1,25 +1 @@
-src/core/commands.py usr/share/schwinn810/core/
-src/core/device.py usr/share/schwinn810/core/
-src/core/__init__.py usr/share/schwinn810/core/
-src/core/progress_gtk.py usr/share/schwinn810/core/
-src/core/progress.glade usr/share/schwinn810/core/
-src/core/progress_text.py usr/share/schwinn810/core/
-src/core/reader_cresta.py usr/share/schwinn810/core/
-src/core/reader.py usr/share/schwinn810/core/
-src/core/reader_schwinn.py usr/share/schwinn810/core/
-src/core/utils.py usr/share/schwinn810/core/
-src/core/writer_csv.py usr/share/schwinn810/core/
-src/web/mmf.py usr/share/schwinn810/web/
-src/web/tcx2web.py usr/share/schwinn810/web/
-src/web/antd/connect.py usr/share/schwinn810/web/antd/
-src/web/antd/__init__.py usr/share/schwinn810/web/antd/
-src/web/antd/plugin.py usr/share/schwinn810/web/antd/
-src/web/antd/LICENSE usr/share/schwinn810/web/antd/
-src/download.py usr/share/schwinn810/
-src/settings.py usr/share/schwinn810/
-src/csv2tcx.py usr/share/schwinn810/
-linux/babelize.sh usr/share/schwinn810/
-linux/schwinn810 usr/bin/
-linux/schwinn810-tray.py usr/share/schwinn810/
linux/schwinn810.desktop etc/xdg/autostart/
-
View
1  linux/schwinn810
@@ -17,5 +17,6 @@ mkdir -p -m 2775 "$DIR/$YEAR"
/usr/share/schwinn810/download.py $DEBUG $HOOK \
--port $PORT \
--progress gtk \
+ --read-settings \
--dir "$DIR/$YEAR" && \
[ "$NOTIFY" ] && notify-send -u low -c transfer.complete "Schwinn 810 GPS watch" "Data extracted"
View
32 src/core/device.py
@@ -8,7 +8,7 @@
from utils import unpack_bcd
import logging
# from collections import namedtuple
-from datetime import datetime
+from datetime import datetime, timedelta
from reader_schwinn import SchwinnReader
from reader_cresta import CrestaReader
@@ -19,10 +19,10 @@ class NotConnected(Exception): pass
class Device:
""" Device class to communicate with Schwinn 810 """
- def __init__(self, device=None):
+ def __init__(self, device=None, debug=False):
self.device = device
+ self._debug = debug
self.dump = False
- self.debug = False
self.connected = False
self.port = None
self.reader = None
@@ -62,14 +62,14 @@ def connect(self):
else:
self.connected = True
- if self.debug:
+ if self._debug:
self.backup = open(os.path.join(tempfile.gettempdir(), "schwinn810.bin"), mode="wb")
self.backup.write(raw)
(ee, e1, e2, e3, bcd1, bcd2, bcd3, serial, v1, v2, sign1) = struct.unpack("sBBBBBB6s6s7s2xI", raw)
if sign1: # 0x0130ff00
raw = self.port.read(4)
- if self.debug:
+ if self._debug:
self.backup.write(raw)
(sign2,) = struct.unpack("I", raw)
if sign1 != sign2:
@@ -107,7 +107,10 @@ def read(self, writer, progress=None):
if not self.dump:
self.port.write(READ)
- (tracks, waypoints) = self.reader.read_summary()
+ summary = self.reader.read_summary()
+ tracks = summary['Tracks']
+ waypoints = summary['Waypoints']
+ # (tracks, waypoints) = self.reader.read_summary()
_log.info("We've got %d tracks and %d waypoints to download" % (tracks, waypoints))
tracks_with_points = self._read_tracks(writer, tracks)
@@ -126,7 +129,9 @@ def read(self, writer, progress=None):
progress.point(thePoint, summary['Points'])
point = self.reader.read_point()
point['Track'] = summary['Track']
- point['Time'] = datetime.combine(summary['Start'], point['Time'])
+ point['Time'] = datetime.combine(summary['Start'].date(), point['Time'])
+ if summary['Start'] > point['Time']:
+ point['Time'] += timedelta(days=1)
writer.add_point(point)
writer.commit()
@@ -134,14 +139,23 @@ def read(self, writer, progress=None):
wpt = self.reader.read_waypoint()
writer.add_waypoint(wpt)
+ self.reader.read_end()
+
+ def read_settings(self, writer):
+ if not self.dump:
+ self.port.write(READ_SETTINGS)
+
+ s = self.reader.read_settings()
+ writer.save_settings(s)
+
def clear(self):
- if not self.dump and self.debug:
+ if not self.dump and self._debug:
self.port.write(DELETE)
else:
_log.info("Debug is required for deletion for now")
def close(self):
- if self.debug:
+ if self._debug:
self.backup.close()
if not self.dump:
View
9 src/core/reader_cresta.py
@@ -16,8 +16,10 @@ def __init__(self, port, dump=None):
def read_summary(self):
raw = self.read(0x20)
- (tracks,) = struct.unpack("=28xH2x", raw)
- return (tracks, 0)
+ s = {}
+ (s['T1'], s['T2'] , s['24hr'], s['Tracks']) = \
+ struct.unpack("<2B 6x B 19x H2x", raw)
+ return s
def read_track(self):
raw = self.read(0x20)
@@ -84,5 +86,8 @@ def read_point(self):
point['InZone'] = izhh*3600 + izmm*60 + izss
return point
+ def read_end(self):
+ raw = self.read(0x20)
+
if __name__ == '__main__':
pass
View
39 src/core/reader_schwinn.py
@@ -6,6 +6,7 @@
import logging
from datetime import datetime, time, date
from reader import *
+# from binascii import hexlify
_log = logging.getLogger(__name__)
@@ -16,7 +17,13 @@ def __init__(self, port, dump=None):
def read_summary(self):
raw = self.read(0x24)
- return struct.unpack("=28xHH4x", raw)
+ s = {}
+ (s['T1'], s['T2'] , s['24hr'], s['Tracks'], s['Waypoints'], sign) = \
+ struct.unpack("<2B 6x B 19x 2H 3x B", raw)
+ # a = hexlify(raw)
+ # _log.debug(a)
+ # return struct.unpack("=28xHH4x", raw)
+ return s
def read_track(self):
raw = self.read(0x24)
@@ -58,12 +65,12 @@ def read_lap(self):
def read_points_summary(self):
raw = self.read(0x24)
- (min1, hr1, dd1, mm1, yr1, lap_count, hrm, pts, name0, ahr, min2, hr2, dd2, mm2, yr2, sign) = \
- struct.unpack(">x5BH4xBxHxx7sB5B4xB", raw)
+ (sec1, min1, hr1, dd1, mm1, yr1, lap_count, hrm, pts, name0, ahr, min2, hr2, dd2, mm2, yr2, sign) = \
+ struct.unpack(">6BH4xBxHxx7sB5B4xB", raw)
if 0xFA != sign:
raise BadSignature
track_name = name0.decode('ascii')
- return {'Track': track_name, 'Points': pts, 'Start': date(2000+yr1, mm1, dd1)}
+ return {'Track': track_name, 'Points': pts, 'Start': datetime(2000+yr1, mm1, dd1, hr1, min1, sec1)}
def read_point(self):
raw = self.read(0x24)
@@ -99,5 +106,29 @@ def read_waypoint(self):
wpt['Elevation'] = z/1e2
return wpt
+ def read_end(self):
+ raw = self.read(0x24)
+ # a = hexlify(raw)
+ # _log.debug(a)
+
+ def read_settings(self):
+ """ Autolap: off, 0.4, 1, 2, 3, 4, 5 """
+ raw = self.read(0x25)
+ # a = hexlify(raw)
+ # _log.debug(a)
+ s = {}
+ (s['Female'], s['Age'], s['Metric'], s['x3'], s['kg'], s['cm'], s['zone_active'], \
+ s['zone1_low'], s['zone1_high'], s['zone2_low'], s['zone2_high'], s['zone3_low'],\
+ s['zone3_high'], s['zone_alarm'], s['x5'], s['Autolap'], s['Contrast'], s['x8'], s['NightMode'], \
+ s['y2'], s['lb'], s['in'], s['24hr'], s['y6'], s['y7'], s['y8'], s['z1'], s['z2'], sign1, sign2) = \
+ struct.unpack("=28B2I", raw)
+ # contrast 8 => 50%
+ # x5=alert
+ # raw = self.read(0x24)
+ # a = hexlify(raw)
+ # _log.debug(a)
+ # _log.debug(s)
+ return s
+
if __name__ == '__main__':
pass
View
15 src/core/writer_csv.py
@@ -21,7 +21,11 @@ class Writer:
"InZone", "y4", "Elevation", "Track"]
point_keys = ["Distance", "Speed", "Time", "Heart", "x1", "InZone", \
"Latitude", "Longitude", "kcal", "Elevation", "No", "Track"]
- waypoint_keys = ["Timestamp", "Name", "Latitude", "Longitude","x1","x2","Elevation","No"]
+ waypoint_keys = ["Time", "Name", "Latitude", "Longitude","x1","x2","Elevation","No"]
+ settings_keys = ["Female", "Age", "Metric", "x3", "kg", "cm", "zone_active", \
+ "zone1_low", "zone1_high", "zone2_low", "zone2_high", "zone3_low",\
+ "zone3_high", "zone_alarm", "x5", "Autolap", "Contrast", "x8", "NightMode", \
+ "y2", "lb", "in", "24hr", "y6", "y7", "y8", "z1", "z2"]
def __init__(self, dir, hook=None):
self.dir = dir
@@ -85,9 +89,12 @@ def add_waypoint(self, wp):
""" Append point to a database """
self.wptWriter.writerow(wp)
- def __del__(self):
- # self.lapFile.close()
- _log.info("Writer destroyed")
+ def save_settings(self, s):
+ name = os.path.join(self.dir, "settings.csv")
+ f = open(name, "wb", **open_extra)
+ w = csv.DictWriter(f, self.settings_keys)
+ w.writeheader()
+ w.writerow(s)
if __name__ == '__main__':
pass
View
9 src/download.py
@@ -2,6 +2,7 @@
from __future__ import print_function
from core.device import Device, SerialException
from core.writer_csv import Writer
+# from extra.writer_sqlite import SQLiteWriter
from core.progress_text import TextProgress
import argparse, os, sys
import logging
@@ -32,6 +33,8 @@ def main():
parser.add_argument('--progress', choices=['none', 'text', 'gtk', 'qt'],
default=['text'],
help='Progress indicator')
+ parser.add_argument('--read-settings', action='store_true',
+ help='Retrieve settings from watch')
# parser.add_argument('--add-year', dest='add_year', action='store_true',
# help='Creates subfolder in dir named after the current year')
# parser.add_argument('--add-id', dest='add_id', action='store_true',
@@ -40,8 +43,8 @@ def main():
args = parser.parse_args()
try:
- d = Device(args.port[0])
- d.debug = args.debug
+ d = Device(args.port[0], args.debug)
+ # w = SQLiteWriter(args.dir[0], args.hook[0])
w = Writer(args.dir[0], args.hook[0])
p = None
if args.progress != 'none':
@@ -61,6 +64,8 @@ def main():
except ImportError:
_log.error('Failed to create QT backend')
d.read(w, p)
+ if args.read_settings:
+ d.read_settings(w)
d.close()
except SerialException as e:
_log.fatal("Port can't be opened :(")
View
0  src/extra/__init__.py
No changes.
Please sign in to comment.
Something went wrong with that request. Please try again.