In [1]:
import os
import pandas as pd
from datetime import datetime

In [2]:
folders = [i for i in os.listdir(os.getcwd()) if '_bt' in i]
folders


Out[2]:
['20160126_bt1',
 '20160126_bt2',
 '20160126_bt5',
 '20160126_bt8',
 '20160127_bt1',
 '20160127_bt6',
 '20160127_bt8',
 '20160127_bt9',
 '20160128_bt1',
 '20160128_bt2',
 '20160128_bt6',
 '20160128_bt8',
 '20160128_bt9']

In [3]:
# In this cell, we concatenate all of the data together.
master_data = pd.DataFrame()

for folder in folders:
    data = pd.read_csv('{0}/data.txt'.format(folder), header=None)
    data.columns = ['tracker_id', 'dBm', 'year', 'month', 'day', 'hour', 'minute', 'second']
    data['base_station_id'] = folder.split('_')[1]

    master_data = master_data.append(data)
    
master_data['date'] = master_data.apply(lambda x: datetime(x['year'], x['month'], x['day'], x['hour'], x['minute'], x['second']), axis=1)
master_data = master_data.drop_duplicates()
master_data.reset_index(drop=True, inplace=True)
len(master_data)


Out[3]:
8253

Notes:

The tracker IDs that were deployed are:

  • F4:B8:5E:C4:54:BE
  • F4:B8:5E:DD:42:D2
  • F4:B8:5E:C4:5F:8C
  • F4:B8:5E:C4:8F:EE
  • 68:9E:19:11:86:DB
  • F4:B8:5E:C4:63:25
  • 74:DA:EA:A8:9D:0F
  • F4:B8:5E:DC:49:F8

In [4]:
tracker_ids_time = {'F4:B8:5E:C4:54:BE':datetime(2016, 1, 28, 12, 1, 0),
                    'F4:B8:5E:DD:42:D2':datetime(2016, 1, 28, 9, 52, 0),
                    'F4:B8:5E:C4:5F:8C':datetime(2016, 1, 28, 10, 12, 0),
                    'F4:B8:5E:C4:8F:EE':datetime(2016, 1, 26, 9, 59, 0),
                    '68:9E:19:11:86:DB':datetime(2016, 1, 26, 9, 27, 0),
                    'F4:B8:5E:C4:63:25':datetime(2016, 1, 26, 11, 15, 0),
                    '74:DA:EA:A8:9D:0F':datetime(2016, 1, 26, 10, 55, 0),
                    'F4:B8:5E:DC:49:F8':datetime(2016, 1, 26, 10, 19, 0),}

In [5]:
master_data = master_data[master_data['tracker_id'].isin(tracker_ids_time.keys())]
master_data.head()


Out[5]:
tracker_id dBm year month day hour minute second base_station_id date
0 F4:B8:5E:C4:8F:EE -90 2016 1 18 14 21 0 bt1 2016-01-18 14:21:00
1 F4:B8:5E:C4:8F:EE -91 2016 1 18 14 21 30 bt1 2016-01-18 14:21:30
2 F4:B8:5E:C4:8F:EE -89 2016 1 18 14 22 32 bt1 2016-01-18 14:22:32
3 74:DA:EA:A8:9D:0F -89 2016 1 18 14 25 2 bt1 2016-01-18 14:25:02
4 F4:B8:5E:C4:8F:EE -83 2016 1 18 14 25 2 bt1 2016-01-18 14:25:02

Time filters for base stations

On each of the listed days, the Tiki base stations were set up at:

  • 26 Jan: 12:37 pm
  • 27 Jan: 9:42 am
  • 28 Jan: 8:25 am

In [6]:
day1_start = datetime(2016, 1, 26, 12, 37, 0)
day2_start = datetime(2016, 1, 27, 9, 42, 0)
day3_start = datetime(2016, 1, 28, 8, 25, 0)

day1_end = datetime(2016, 1, 26, 16, 30, 0)
day2_end = datetime(2016, 1, 27, 16, 30, 0)
day3_end = datetime(2016, 1, 28, 16, 30 ,0)

Perform the filtering for each tracker. Legitimate pings are the ones that occurred between the start and end times of each day, inclusive.


In [7]:
tracker_dfs = dict()

for i, (tracker_id, dt) in enumerate(tracker_ids_time.items()):
    # tracker_id = some hexadecimal number.
    # dt = the datetime object indicating the time at which the seal was finished sampling
    tracker_dfs[tracker_id] = master_data[(master_data.tracker_id == tracker_id) & (master_data.date >= dt)]
    trkr = tracker_dfs[tracker_id]
    trkr = trkr[((trkr['date'] >= day1_start) & (trkr['date'] <= day1_end)) | \
                ((trkr['date'] >= day2_start) & (trkr['date'] <= day2_end)) | \
                ((trkr['date'] >= day3_start) & (trkr['date'] <= day3_end))]
    tracker_dfs[tracker_id] = trkr

Below, we will print out each tracker as well as the number of pings it gave to any base station, and the time at which the pings occurred.


In [8]:
print(list(tracker_dfs.keys())[0])
tracker_dfs[list(tracker_dfs.keys())[0]]


F4:B8:5E:C4:54:BE
Out[8]:
tracker_id dBm year month day hour minute second base_station_id date

In [9]:
print(list(tracker_dfs.keys())[1])
tracker_dfs[list(tracker_dfs.keys())[1]]


F4:B8:5E:DC:49:F8
Out[9]:
tracker_id dBm year month day hour minute second base_station_id date

In [10]:
print(list(tracker_dfs.keys())[2])
tracker_dfs[list(tracker_dfs.keys())[2]]


F4:B8:5E:C4:63:25
Out[10]:
tracker_id dBm year month day hour minute second base_station_id date

In [11]:
print(list(tracker_dfs.keys())[3])
tracker_dfs[list(tracker_dfs.keys())[3]]


F4:B8:5E:DD:42:D2
Out[11]:
tracker_id dBm year month day hour minute second base_station_id date
5959 F4:B8:5E:DD:42:D2 -101 2016 1 28 9 53 34 bt6 2016-01-28 09:53:34

The above seal is the only one that stuck around, within some proximity, to a base station (BT5). From a technical standpoint, this is one example of a successful deployment of the tracker, in that we are able to detect a ping.


In [12]:
print(list(tracker_dfs.keys())[4])
tracker_dfs[list(tracker_dfs.keys())[4]]


74:DA:EA:A8:9D:0F
Out[12]:
tracker_id dBm year month day hour minute second base_station_id date
4854 74:DA:EA:A8:9D:0F -99 2016 1 27 13 44 43 bt2 2016-01-27 13:44:43

In [13]:
print(list(tracker_dfs.keys())[5])
tracker_dfs[list(tracker_dfs.keys())[5]]


68:9E:19:11:86:DB
Out[13]:
tracker_id dBm year month day hour minute second base_station_id date

In [14]:
print(list(tracker_dfs.keys())[6])
tracker_dfs[list(tracker_dfs.keys())[6]]


F4:B8:5E:C4:8F:EE
Out[14]:
tracker_id dBm year month day hour minute second base_station_id date
2630 F4:B8:5E:C4:8F:EE -99 2016 1 26 12 37 2 bt5 2016-01-26 12:37:02
2631 F4:B8:5E:C4:8F:EE -96 2016 1 26 12 38 32 bt5 2016-01-26 12:38:32
2632 F4:B8:5E:C4:8F:EE -97 2016 1 26 13 33 13 bt5 2016-01-26 13:33:13
2633 F4:B8:5E:C4:8F:EE -98 2016 1 26 13 33 43 bt5 2016-01-26 13:33:43
2634 F4:B8:5E:C4:8F:EE -99 2016 1 26 13 34 14 bt5 2016-01-26 13:34:14
2635 F4:B8:5E:C4:8F:EE -93 2016 1 26 14 3 20 bt5 2016-01-26 14:03:20
2636 F4:B8:5E:C4:8F:EE -93 2016 1 26 14 4 50 bt5 2016-01-26 14:04:50
2637 F4:B8:5E:C4:8F:EE -95 2016 1 26 14 5 51 bt5 2016-01-26 14:05:51
2638 F4:B8:5E:C4:8F:EE -96 2016 1 26 14 6 52 bt5 2016-01-26 14:06:52
2639 F4:B8:5E:C4:8F:EE -96 2016 1 26 14 7 23 bt5 2016-01-26 14:07:23
2640 F4:B8:5E:C4:8F:EE -96 2016 1 26 14 10 24 bt5 2016-01-26 14:10:24
2641 F4:B8:5E:C4:8F:EE -94 2016 1 26 14 11 56 bt5 2016-01-26 14:11:56
2642 F4:B8:5E:C4:8F:EE -94 2016 1 26 14 28 30 bt5 2016-01-26 14:28:30
2643 F4:B8:5E:C4:8F:EE -97 2016 1 26 14 33 1 bt5 2016-01-26 14:33:01
2644 F4:B8:5E:C4:8F:EE -95 2016 1 26 14 33 31 bt5 2016-01-26 14:33:31
2645 F4:B8:5E:C4:8F:EE -98 2016 1 26 14 34 1 bt5 2016-01-26 14:34:01
2646 F4:B8:5E:C4:8F:EE -97 2016 1 26 14 36 2 bt5 2016-01-26 14:36:02
2647 F4:B8:5E:C4:8F:EE -95 2016 1 26 15 14 39 bt5 2016-01-26 15:14:39
2648 F4:B8:5E:C4:8F:EE -95 2016 1 26 15 17 11 bt5 2016-01-26 15:17:11
2649 F4:B8:5E:C4:8F:EE -97 2016 1 26 15 18 11 bt5 2016-01-26 15:18:11
2650 F4:B8:5E:C4:8F:EE -98 2016 1 26 15 20 12 bt5 2016-01-26 15:20:12
2651 F4:B8:5E:C4:8F:EE -98 2016 1 26 15 22 14 bt5 2016-01-26 15:22:14
2652 F4:B8:5E:C4:8F:EE -96 2016 1 26 15 22 44 bt5 2016-01-26 15:22:44
2653 F4:B8:5E:C4:8F:EE -100 2016 1 26 15 54 50 bt5 2016-01-26 15:54:50

In [15]:
print(list(tracker_dfs.keys())[7])
tracker_dfs[list(tracker_dfs.keys())[7]]


F4:B8:5E:C4:5F:8C
Out[15]:
tracker_id dBm year month day hour minute second base_station_id date
5981 F4:B8:5E:C4:5F:8C -95 2016 1 28 10 45 19 bt6 2016-01-28 10:45:19

Just by simply eyeballing the data, this is what it looks like:

  1. With the exception of 1 seal that stuck around for 3 hours after being sampled, the other seals only registered a single ping, or were never re-discovered after placing the tracker on its head.
  2. This "single ping" - I'm not sure what explains it best:
    1. Did the tracker get damaged soon after being placed on the seal's head? If so, could a better solution be engineered, say via 3D printing a case to make it easier to keep waterproofed and from being crushed?
    2. Did the seal pups move into a different location soon after being sampled? If so, could densely deploying more Tiki trackers, over a larger area, help with coverage? We should raise money for this next year, say, via Experiment.

Conclusions

  1. Two of the most probable problems to solve:
    1. Casing - by 3D printing (can prototype if we have a cheap 3D printer in the lab, and then mass-produce at the Broad or MIT Machine Shop, both of which have 3D printers)
    2. Proximity - by deploying more trackers.

Let's raise money on Experiment! This should help us cover the costs of making more tiki base stations, and deploying more Bluetooth tags.


In [ ]:


In [ ]:


In [ ]: