def test_uniq(self): """ Test removal of duplicate removal """ dives = (kd.Dive(datetime=datetime(2011, 5, 5)), kd.Dive(datetime=datetime(2011, 5, 5)), kd.Dive(datetime=datetime(2011, 5, 6))) ud = list(kd.uniq_dives(dives)) self.assertEquals(2, len(ud))
def test_dive_profiles_df(self): """ Test dive profiles data frame creation """ p1 = ( kd.Sample(time=0, depth=10.0, temp=15.0, alarm=False), kd.Sample(time=10, depth=20.0, temp=14.0, alarm=False), kd.Sample(time=20, depth=10.0, temp=13.0, alarm=False), ) p2 = ( kd.Sample(time=1, depth=10.0, temp=15.0, alarm=False), kd.Sample(time=11, depth=20.0, temp=14.0, deco_time=4, deco_depth=9, alarm=False), kd.Sample(time=21, depth=10.0, temp=13.0, alarm=False), ) p3 = ( kd.Sample(time=2, depth=10.0, temp=15.0, alarm=False), kd.Sample(time=12, depth=20.0, temp=14.0, deco_time=1, deco_depth=6, alarm=True), kd.Sample(time=22, depth=12.0, temp=11.0, alarm=False), kd.Sample(time=23, depth=11.0, temp=12.0, alarm=False), kd.Sample(time=25, depth=10.0, temp=11.0, alarm=False), ) d1 = kd.Dive(profile=p1) d2 = kd.Dive(profile=p2) d3 = kd.Dive(profile=p3) d = dive_profiles_df((d1, d2, d3)) self.assertEquals(11, d.nrow) self.assertEquals(13, d.ncol) self.assertEquals((1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3), tuple(d[0])) self.assertEquals( (10.0, 20.0, 10.0, 10.0, 20.0, 10.0, 10.0, 20.0, 12.0, 11.0, 10.0), tuple(d[1])) self.assertEquals((0, 10, 20, 1, 11, 21, 2, 12, 22, 23, 25), tuple(d[2]))
def dives(self, dump): """ Convert dive data into UDDF format. """ ostc_data = ostc_parser.get_data(dump.data) for h, p in ostc_parser.profiles(ostc_data.profiles): log.debug('header: {}'.format(hexlify(h))) log.debug('profile: {}'.format(hexlify(p))) header = ostc_parser.header(h) dive_data = ostc_parser.dive_data(header, p) # set time of the start of dive st = datetime(2000 + header.year, header.month, header.day, header.hour, header.minute) # ostc dive computer saves time at the end of dive in its # memory, so substract the dive time; # sampling amount is substracted as well as below (0, 0) # waypoint is added duration = timedelta(minutes=header.dive_time_m, seconds=header.dive_time_s + header.sampling) st -= duration # firmware ver < 1.91 has no average depth information avg_depth = header.avg_depth / 100.0 \ if hasattr(header, 'avg_depth') else None # firmware ver < 1.91 has no deco type information dive_mode = None if hasattr(header, 'deco_type'): if header.deco_type in (0, 4): dive_mode = 'opencircuit' elif header.deco_type in (2, 5): dive_mode = 'closedcircuit' elif header.doc_type == 3: dive_mode = 'apnoe' try: profile = list(self._get_profile(header, dive_data)) yield kd.Dive(datetime=st, depth=header.max_depth / 100.0, duration=duration.seconds, temp=C2K(header.min_temp / 10.0), avg_depth=avg_depth, mode=dive_mode, profile=profile) except ValueError as ex: log.error('invalid dive {0.year:>02d}-{0.month:>02d}-{0.day:>02d}' \ ' {0.hour:>02d}:{0.minute:>02d}' \ ' max depth={0.max_depth}'.format(header))
def test_dive_reenum(self): """ Test re-enumerating dives """ kl.enum_dives([self.fin]) r = ku.find(self.fin, '//uddf:dive//uddf:divenumber/text()') assert ['1', '2', '3'] == list(r) d = kd.Dive(datetime=datetime(2010, 1, 2, 5, 7), depth=33.0, duration=3540) kl.add_dive(d, self.fin) kl.enum_dives([self.fin]) # re-enumerate r = ku.find(self.fin, '//uddf:dive//uddf:divenumber/text()') self.assertEquals(['1', '2', '3', '4'], list(r))
def test_dive_add_with_buddy(self): """ Test adding dive with time, depth, duration and buddy """ f = '{}/dive_add_buddy.uddf'.format(self.tdir) doc = ku.create() ku.create_buddy_data(doc, id='b1', fname='F', lname='N') ku.save(doc, f) d = kd.Dive(datetime=datetime(2010, 1, 2, 5, 7), depth=33.0, duration=3540) kl.add_dive(d, f, qbuddies=['b1']) nodes = ku.find(f, '//uddf:dive') dn = next(nodes) self.assertEquals('b1', ku.xp_first(dn, './/uddf:link/@ref'))
def test_dive_add_with_site(self): """ Test adding dive with time, depth, duration and dive site """ f = '{}/dive_add_site.uddf'.format(self.tdir) doc = ku.create() ku.create_site_data(doc, id='s1', location='L1', name='N1') ku.save(doc, f) d = kd.Dive(datetime=datetime(2010, 1, 2, 5, 7), depth=33.0, duration=3102) kl.add_dive(d, f, qsite='s1') nodes = ku.find(f, '//uddf:dive') dn = next(nodes) self.assertEquals('s1', ku.xp_first(dn, './/uddf:link/@ref'))
def __call__(self, args): """ Execute command for adding dives into logbook file. """ import kenozooid.logbook as kl import kenozooid.data as kd from dateutil.parser import parse as dparse lfile = args.logbook datetime = dparse(args.datetime) depth = float(args.depth) duration = float(args.duration) * 60 site = args.site buddy = args.buddy dive = kd.Dive(datetime=datetime, depth=depth, duration=duration) kl.add_dive(dive, lfile, qsite=site, qbuddies=buddy)
def test_dive_add(self): """ Test adding dive with time, depth and duration """ f = '{}/dive_add.uddf'.format(self.tdir) d = kd.Dive(datetime=datetime(2010, 1, 2, 5, 7), depth=33.0, duration=3540) kl.add_dive(d, f) nodes = ku.find(f, '//uddf:dive') dn = next(nodes) self.assertTrue(next(nodes, None) is None) self.assertEquals('2010-01-02T05:07:00', ku.xp_first(dn, './/uddf:datetime/text()')) self.assertEquals('33.0', ku.xp_first(dn, './/uddf:greatestdepth/text()')) self.assertEquals('3540', ku.xp_first(dn, './/uddf:diveduration/text()'))
def test_dive_data_injection(self): """ Test dive data injection """ p1 = ( kd.Sample(time=0, depth=10.0, temp=15.0, alarm=False), kd.Sample(time=10, depth=20.0, temp=14.0, alarm=False), kd.Sample(time=20, depth=10.0, temp=13.0, alarm=False), ) p2 = ( kd.Sample(time=1, depth=10.0, temp=15.0, alarm=False), kd.Sample(time=11, depth=20.0, temp=14.0, deco_time=4, deco_depth=9, alarm=False), kd.Sample(time=21, depth=10.0, temp=13.0, alarm=False), ) p3 = ( kd.Sample(time=2, depth=10.0, temp=15.0, alarm=False), kd.Sample(time=12, depth=20.0, temp=14.0, deco_time=1, deco_depth=6, alarm=True), kd.Sample(time=22, depth=12.0, temp=11.0, alarm=False), kd.Sample(time=23, depth=11.0, temp=12.0, alarm=False), kd.Sample(time=25, depth=10.0, temp=11.0, alarm=False), ) d1 = kd.Dive(number=1, datetime=datetime(2011, 10, 11), depth=31.0, duration=2010, temp=12, profile=p1) d2 = kd.Dive(number=2, datetime=datetime(2011, 10, 12), depth=32.0, duration=2020, temp=14, profile=p2) d3 = kd.Dive(number=3, datetime=datetime(2011, 10, 13), depth=33.0, duration=2030, temp=None, profile=p3) inject_dive_data((d1, d2, d3)) d_df = ro.globalenv['kz.dives'] self.assertEquals(3, d_df.nrow) self.assertEquals(6, d_df.ncol) self.assertEquals((31.0, 32.0, 33.0), tuple(d_df[2])) self.assertEquals((2010, 2020, 2030), tuple(d_df[3])) self.assertEquals((12, 14, ro.NA_Real), tuple(d_df[4])) p_df = ro.globalenv['kz.profiles'] self.assertEquals(11, p_df.nrow) self.assertEquals(13, p_df.ncol) self.assertEquals((1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3), tuple(p_df[0])) self.assertEquals( (10.0, 20.0, 10.0, 10.0, 20.0, 10.0, 10.0, 20.0, 12.0, 11.0, 10.0), tuple(p_df[1])) self.assertEquals((0, 10, 20, 1, 11, 21, 2, 12, 22, 23, 25), tuple(p_df[2]))
def parse_dive(self, buffer, size, fingerprint, fsize, pdata, parser, boot_time, dives): """ Callback used by libdivecomputer's library function to extract dives from a device and put it into dives queue. :Parameters: buffer Buffer with binary dive data. size Size of buffer dive data. fingerprint Fingerprint buffer. fsize Size of fingerprint buffer. pdata Parser user data (nothing at the moment). parser libdivecomputer parser instance. boot_time Sensus Ultra boot time. dives Queue of dives to be consumed by caller. """ lib = ct.CDLL('libdivecomputer.so.0') lib.parser_set_data(parser, buffer, size) header = _dive_header(buffer) log.debug('parsing dive: {0}'.format(header)) # dive time is in seconds since boot time # interval is substracted due to depth=0, time=0 sample injection st = datetime.fromtimestamp(boot_time - header.interval + header.time) log.debug('got dive time: {0}'.format(st)) samples = [] parse_sample = partial(self.parse_sample, dive_header=header, sdata={}, sq=samples) f = FuncSample(parse_sample) lib.parser_samples_foreach(parser, f, None) log.debug('removing {} endcount samples'.format(header.endcount)) del samples[-header.endcount:] # dive summary after endcount removal max_depth = max(samples, key=operator.attrgetter('depth')).depth min_temp = min(samples, key=operator.attrgetter('temp')).temp duration = samples[-1].time + header.interval # each dive starts below DiveHeader.threshold, therefore inject # first sample required by UDDF samples.insert(0, kd.Sample(depth=0.0, time=0)) # each dive ends at about DiveHeader.threshold depth, therefore # inject last sample required by UDDF samples.append(kd.Sample(depth=0.0, time=duration)) # finally, create dive data dive = kd.Dive(datetime=st, depth=max_depth, duration=duration, temp=min_temp, profile=samples) try: dives.put(dive, timeout=30) except Full: log.error('could not parse dives due to internal queue timeout') return 0 return 1