Skip to content

Commit

Permalink
Merge pull request #47 from HumanDynamics/develop
Browse files Browse the repository at this point in the history
Remove badge caching
  • Loading branch information
OrenLederman authored Dec 5, 2018
2 parents 664076b + 6a57daa commit b7f3d48
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 146 deletions.
25 changes: 15 additions & 10 deletions src/badge.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,9 @@ def badge_id(self):
def observed_id(self):
return self.observed_id

@property
@property
def project_id(self):
return self.project_id
return self.project_id

@property
def last_proximity_ts(self):
Expand All @@ -324,6 +324,10 @@ def last_contacted_ts(self):
def last_unsync_ts(self):
return self.__last_unsync_ts

@property
def last_seen_ts(self):
return self.__last_seen_ts

@property
def last_voltage(self):
return self.last_voltage
Expand Down Expand Up @@ -389,11 +393,11 @@ def is_newer_audio_ts(self, audio_ts_int, audio_ts_fract):
# no value is set yetyet
return True

def __init__(self,addr,logger, key,badge_id,project_id, init_audio_ts_int=None, init_audio_ts_fract=None, init_proximity_ts=None, init_voltage=None, init_contact_ts=None,init_unsync_ts=None, observed_id=None):
def __init__(self,addr,logger, key,badge_id,project_id, init_audio_ts_int=None, init_audio_ts_fract=None, init_proximity_ts=None, init_voltage=None, init_contact_ts=None,init_unsync_ts=None, init_seen_ts=None, observed_id=None):
#if self.children.get(key):
# return self.children.get(key)
self.children[key] = self
self.key = key
self.children[key] = self
self.key = key
self.addr = addr
self.logger = adapter = BadgeAddressAdapter(logger, {'addr': addr})
self.badge_id = badge_id
Expand All @@ -410,6 +414,7 @@ def __init__(self,addr,logger, key,badge_id,project_id, init_audio_ts_int=None,
self.__last_proximity_ts = init_proximity_ts
self.__last_contacted_ts = init_contact_ts
self.__last_unsync_ts = init_unsync_ts
self.__last_seen_ts = init_seen_ts

def connect(self):
self.logger.info("Connecting to {}".format(self.addr))
Expand All @@ -425,8 +430,8 @@ def disconnect(self):

# sends status request with UTC time to the badge
def sendStatusRequest(self):
long_epoch_seconds, ts_fract = now_utc_epoch()
self.dlg.expected = Expect.status
long_epoch_seconds, ts_fract = now_utc_epoch()
self.dlg.expected = Expect.status
return self.conn.write('<cLHHB',"s",long_epoch_seconds,ts_fract,int(self.badge_id), int(self.project_id))
#return self.conn.write('<cLH',"s",long_epoch_seconds,ts_fract)

Expand Down Expand Up @@ -595,7 +600,7 @@ def pull_data(self, activate_audio, activate_proximity):

self.logger.info("Connected")
self.last_contacted_ts=time.time()

# Sending status (and setting ids)
self.logger.info("Sending status request (Badge id : {} , project id : {})".format(self.badge_id, self.project_id))
with timeout(seconds=5, error_message="StartusRequest timeout (wrong firmware version?)"):
Expand Down Expand Up @@ -689,7 +694,7 @@ def pull_data(self, activate_audio, activate_proximity):

return retcode


def print_bytes(data):
"""
Prints a given string as an array of unsigned bytes
Expand Down Expand Up @@ -777,7 +782,7 @@ def ts_and_fract_to_float(ts_int,ts_fract):
#logger.setLevel(logging.DEBUG)

b = Badge("AAAAA",logger,"ABCDE",100,10,100,1,250)

print(b.last_audio_ts_int,b.last_audio_ts_fract)
b.set_audio_ts(110,1)
print(b.last_audio_ts_int, b.last_audio_ts_fract)
Expand Down
18 changes: 12 additions & 6 deletions src/badge_hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ def dialogue(bdg, activate_audio, activate_proximity, mode="server"):

# update badge object to hold latest timestamps
last_chunk = bdg.dlg.chunks[-1]
logger.debug("Setting last badge audio timestamp to {} {}".format(last_chunk.ts, last_chunk.fract))
if bdg.is_newer_audio_ts(last_chunk.ts, last_chunk.fract):
logger.debug("Setting last badge audio timestamp to {} {}".format(last_chunk.ts, last_chunk.fract))
bdg.set_audio_ts(last_chunk.ts, last_chunk.fract)
else:
logger.debug("Keeping existing timestamp ({}.{}) for {}. Last chunk timestamp was: {}.{}"
Expand Down Expand Up @@ -464,14 +464,20 @@ def pull_devices(mgr, mgrb, start_recording):

# now the actual data collection
for device in scanned_devices:
b = mgr.badges.get(device['mac'])
# try to update latest badge timestamps from the server
mgr.pull_badge(b.addr)
mac = device['mac']
pull_success = mgr.pull_badge(mac)
if not pull_success:
logger.warn("""Problem pulling badge from server\n
Skipping badge with mac {} until next full badge list refresh"""
.format(mac))
continue
b = mgr.badges.get(mac)
# pull data
dialogue(b, activate_audio, activate_proximity, mode)

# update timestamps on server
mgr.send_badge(device['mac'])
mgr.send_badge(mac)

time.sleep(2) # requires sleep between devices

Expand All @@ -495,7 +501,7 @@ def pull_devices(mgr, mgrb, start_recording):
.format(bcn.observed_id,observed_project_id,bcn.badge_id,bcn.project_id))

bcn.last_seen_ts = time.time()

mgrb.send_beacon(device['mac'])

# Update beacons with wrong id or project id
Expand Down
83 changes: 14 additions & 69 deletions src/badge_manager_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,72 +92,8 @@ def _read_badge_from_server(self, badge_key, retry=False, retry_delay_sec=5):

return None

def _update_badge_with_server_badge(self,badge,server_badge):
"""
Updates the timestamp of the given badge if the given server badge has more recent timestamps
When running multiple hubs in the same project, a different hub might have updated these values
already. Therefore, we need to pull the latest values.
:param badge:
:param server_badge:
:return:
"""
mac = badge.addr
server_ts_int = server_badge.last_audio_ts_int
server_ts_fract = server_badge.last_audio_ts_fract
server_ts_last_contacted = server_badge.last_contacted_ts
server_ts_last_unsync = server_badge.last_unsync_ts
if badge.is_newer_audio_ts(server_ts_int, server_ts_fract):
#self.logger.debug("Updating {} with new audio timestamp: {} {}"
# .format(mac, server_ts_int, server_ts_fract))
badge.set_audio_ts(server_ts_int, server_ts_fract)
else:
#self.logger.debug("Keeping existing timestamp for {}. Server values were: {} {}"
# .format(mac, server_ts_int, server_ts_fract))
pass

# proximity
server_proximity_ts = server_badge.last_proximity_ts
if server_proximity_ts > badge.last_proximity_ts:
#self.logger.debug("Updating {} with new proximity timestamp: {}".format(mac, server_proximity_ts))
badge.last_proximity_ts = server_proximity_ts

else:
#self.logger.debug("Keeping existing proximity timestamp for {}. Server value was: {}"
# .format(mac, server_proximity_ts))
pass

if server_ts_last_contacted > badge.last_contacted_ts:
badge.last_contacted_ts = server_ts_last_contacted
else:
pass

if server_ts_last_unsync > badge.last_unsync_ts:
badge.last_unsync_ts = server_ts_last_unsync
else:
pass

# updates project id and badge id
badge.badge_id = server_badge.badge_id
badge.project_id = server_badge.project_id

def pull_badges_list(self):
# first time we read from server
if self._badges is None:
server_badges = self._read_badges_list_from_server(retry=True)
self._badges = server_badges
else:
# update list
server_badges = self._read_badges_list_from_server(retry=False)
for mac in server_badges:
if mac not in self._badges:
# new badge
self._badges[mac] = server_badges[mac]
else:
# existing badge. Update if needed
# audio
badge = self._badges[mac]
server_badge = server_badges[mac]
self._update_badge_with_server_badge(badge,server_badge)
self._badges = self._read_badges_list_from_server(retry=True)

def pull_badge(self, mac):
"""
Expand All @@ -168,10 +104,19 @@ def pull_badge(self, mac):
badge = self._badges[mac]
server_badge = self._read_badge_from_server(badge.key)
if server_badge is None:
# this could happen if the badge is removed from the server in between iterations
self.logger.warn("Could not find device {} in server, or communication problem".format(badge.key))
return False
elif server_badge.addr != mac:
# this could happen if a badge is reassigned in between iterations
# and would result in associating the data from the badge with the wrong user
self.logger.warn(
"Badge / Server Mac Address mismatch for badge: {}"
.format(mac))
return False
else:
# update timestamps if more recent
self._update_badge_with_server_badge(badge, server_badge)
self._badges[mac] = server_badge
return True

def send_badge(self, mac):
"""
Expand All @@ -181,7 +126,7 @@ def send_badge(self, mac):
"""
try:
badge = self._badges[mac]
data = {
data = {
'observed_id': badge.observed_id,
'last_audio_ts': badge.last_audio_ts_int,
'last_audio_ts_fract': badge.last_audio_ts_fract,
Expand Down Expand Up @@ -243,7 +188,7 @@ def badges(self):
logging.basicConfig()
logger = logging.getLogger('badge_server')
logger.setLevel(logging.DEBUG)

mgr = BadgeManagerServer(logger=logger)
mgr.pull_badges_list()
print(mgr.badges)
Expand Down
16 changes: 4 additions & 12 deletions src/badge_manager_standalone.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,26 +71,18 @@ def _read_file(self,device_file):
return badges

def pull_badges_list(self):
# first time we read as is
if self._badges is None:
if not self._badges:
file_badges = self._read_file(self._device_file)
self._badges = file_badges
else:
# update list
file_badges = self._read_file(self._device_file)
for mac in file_badges:
if mac not in self._badges:
# new badge
self.logger.debug("Found new badge in file: {}".format(mac))
self._badges[mac] = file_badges[mac]

def pull_badge(self, mac):
"""
Contacts to server (if responding) and updates the given badge data
:param mac:
:return:
:return success?:
"""
pass # not implemented
# Return success so it doesn't break everything else
return True

def send_badge(self, mac):
"""
Expand Down
37 changes: 3 additions & 34 deletions src/beacon_manager_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,47 +88,16 @@ def _read_beacon_from_server(self, beacon_key, retry=False, retry_delay_sec=5):

return None

def _update_beacon_with_server_beacon(self,beacon,server_beacon):
"""
Update the beacon properties from the server's copy
:param beacon:
:param server_beacon:
:return:
"""

# updates project id and badge id
beacon.badge_id = server_beacon.badge_id
beacon.project_id = server_beacon.project_id

def pull_beacons_list(self):
# first time we read from server
if self._beacons is None:
server_beacons = self._read_beacons_list_from_server(retry=True)
self._beacons = server_beacons
else:
# update list
server_beacons = self._read_beacons_list_from_server(retry=False)
for mac in server_beacons:
if mac not in self._beacons:
# new beacon
self._beacons[mac] = server_beacons[mac]
else:
beacon = self._beacons[mac]
server_beacon = server_beacons[mac]
self._update_beacon_with_server_beacon(beacon,server_beacon)
self._beacons = self._read_beacons_list_from_server(retry=True)

def pull_beacon(self, mac):
"""
Contacts to server (if responding) and updates the given badge data
Contacts to server (if responding) and updates the given beacon data
:param mac:
:return:
"""
beacon = self._beacons[mac]
server_beacon = self._read_beacon_from_server(beacon.key)
if server_beacon is None:
self.logger.warn("Could not find device {} in server, or communication problem".format(beacon.key))
else:
self._update_beacon_with_server_beacon(beacon, server_beacon)
raise NotImplementedError()

def send_beacon(self, mac):
"""
Expand Down
21 changes: 6 additions & 15 deletions src/beacon_manager_standalone.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ def _read_file(self,device_file):
devices = []

for line in devices_macs:
if not line.lstrip().startswith('#'):
device_details = line.split()
devices.append(device_details[0])
badge_project_ids.append(device_details[1:3])
if not line.lstrip().startswith('#'):
device_details = line.split()
devices.append(device_details[0])
badge_project_ids.append(device_details[1:3])


#mapping badge id and project id to mac address
Expand All @@ -68,26 +68,17 @@ def _read_file(self,device_file):
return beacons

def pull_beacons_list(self):
# first time we read as is
if self._beacons is None:
if not self._beacons:
file_beacons = self._read_file(self._device_file)
self._beacons = file_beacons
else:
# update list
file_beacons = self._read_file(self._device_file)
for mac in file_beacons:
if mac not in self._beacons:
# new badge
self.logger.debug("Found new badge in file: {}".format(mac))
self._beacons[mac] = file_beacons[mac]

def pull_beacon(self, mac):
"""
Contacts to server (if responding) and updates the given pull_beacon data
:param mac:
:return:
"""
pass # not implemented
raise NotImplementedError()

def send_beacon(self, mac):
"""
Expand Down

0 comments on commit b7f3d48

Please sign in to comment.