Skip to content

Commit ed8c75b

Browse files
committed
Removed closing websession in destructor, and added it as a separate function. Added sphere presence to spheres. Updated data updater for sphere presence.
1 parent 91ae11d commit ed8c75b

7 files changed

Lines changed: 52 additions & 23 deletions

File tree

crownstone_cloud/lib/cloud.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def __init__(
2020
loop: asyncio.AbstractEventLoop = None,
2121
websession: aiohttp.ClientSession = None
2222
) -> None:
23-
self.login_data = {'email': email, 'password': password_to_hash(password)}
23+
self.login_data = {'email': email, 'password': self.password_to_hash(password)}
2424
self.loop = loop or asyncio.get_event_loop()
2525
# set request handler params
2626
RequestHandler.websession = websession or aiohttp.ClientSession(loop=loop)
@@ -29,7 +29,7 @@ def __init__(
2929
self.spheres: Optional[Spheres] = None
3030

3131
def __del__(self):
32-
self.cleanup()
32+
self.reset()
3333

3434
async def initialize(self) -> None:
3535
"""Async initialize the cloud data"""
@@ -68,10 +68,11 @@ async def sync(self) -> None:
6868
# get the data from the sphere attributes
6969
for sphere in self.spheres:
7070
await asyncio.gather(
71+
sphere.update_sphere_presence(),
7172
sphere.crownstones.update(),
7273
sphere.crownstones.update_state(),
7374
sphere.locations.update(),
74-
sphere.locations.update_presence(),
75+
sphere.locations.update_location_presence(),
7576
sphere.users.update()
7677
)
7778
_LOGGER.warning("Cloud data successfully initialized")
@@ -88,15 +89,27 @@ def get_crownstone_by_id(self, crownstone_id) -> Crownstone:
8889
for sphere in self.spheres:
8990
return sphere.crownstones[crownstone_id]
9091

91-
def cleanup(self) -> None:
92+
@staticmethod
93+
def reset() -> None:
94+
"""Cleanup the request handler instance data"""
95+
RequestHandler.access_token = None
96+
RequestHandler.websession = None
97+
RequestHandler.login_data = None
98+
99+
@staticmethod
100+
async def close_session() -> None:
92101
"""Close the websession after we are done"""
93-
self.loop.create_task(RequestHandler.websession.close())
102+
await RequestHandler.websession.close()
94103
_LOGGER.warning("Session closed.")
95104

105+
def close_session_sync(self) -> None:
106+
"""Sync version of close session"""
107+
self.loop.run_until_complete(self.close_session())
96108

97-
def password_to_hash(password):
98-
"""Generate a sha1 password from string"""
99-
if password is None:
100-
return None
101-
pw_hash = hashlib.sha1(password.encode('utf-8'))
102-
return pw_hash.hexdigest()
109+
@staticmethod
110+
def password_to_hash(password):
111+
"""Generate a sha1 password from string"""
112+
if password is None:
113+
return None
114+
pw_hash = hashlib.sha1(password.encode('utf-8'))
115+
return pw_hash.hexdigest()

crownstone_cloud/lib/cloudModels/locations.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ async def update(self) -> None:
2626
for location in location_data:
2727
self.locations[location['id']] = Location(location)
2828

29-
async def update_presence(self) -> None:
29+
async def update_location_presence(self) -> None:
3030
"""Replaces the current presence with that of the cloud."""
3131
presence_data = await RequestHandler.get('Spheres', 'presentPeople', model_id=self.sphere_id)
3232
for presence in presence_data:
@@ -41,7 +41,7 @@ def update_sync(self) -> None:
4141

4242
def update_presence_sync(self) -> None:
4343
"""Sync function for updating the presence"""
44-
self.loop.run_until_complete(self.update_presence())
44+
self.loop.run_until_complete(self.update_location_presence())
4545

4646
def find(self, location_name: str) -> object or None:
4747
"""Search for a sphere by name and return sphere object if found"""

crownstone_cloud/lib/cloudModels/spheres.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def __init__(self, loop: asyncio.AbstractEventLoop, data: dict, user_id: str):
5757
self.locations = Locations(loop, self.cloud_id)
5858
self.users = Users(loop, self.cloud_id)
5959
self.keys: dict = {}
60+
self.present_people = []
6061

6162
@property
6263
def name(self) -> str:
@@ -82,4 +83,10 @@ async def get_keys(self) -> dict:
8283

8384
def get_keys_sync(self) -> dict:
8485
"""Sync get the user keys for this sphere, that can be used for BLE (optional)"""
85-
return self.loop.run_until_complete(self.get_keys())
86+
return self.loop.run_until_complete(self.get_keys())
87+
88+
async def update_sphere_presence(self) -> None:
89+
"""Replaces the current presence with that of the cloud."""
90+
presence_data = await RequestHandler.get('Spheres', 'presentPeople', model_id=self.cloud_id)
91+
for user in presence_data:
92+
self.present_people.append(user['userId'])

crownstone_cloud/util/data_updater.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class CloudDataUpdater:
66
Optional API.
77
Contains callbacks that can be used with the Crownstone SSE lib, or own events.
88
"""
9+
910
def __init__(self, cloud_instance: CrownstoneCloud) -> None:
1011
"""
1112
:param cloud_instance: your instance of the cloud lib.
@@ -35,15 +36,22 @@ def update_presence(self, presence_event) -> None:
3536
PresenceEvent is a class containing: event_type, sphere_id, location_id, user_id.
3637
"""
3738
sphere = self.cloud_instance.spheres.find_by_id(presence_event.sphere_id)
38-
location = sphere.locations.find_by_id(presence_event.location_id)
3939
user = sphere.users.find_by_id(presence_event.user_id)
4040

4141
if presence_event.type == 'enterLocation':
42+
location = sphere.locations.find_by_id(presence_event.location_id)
4243
location.present_people.append(user.cloud_id)
4344

4445
if presence_event.type == 'exitLocation':
46+
location = sphere.locations.find_by_id(presence_event.location_id)
4547
location.present_people.remove(user.cloud_id)
4648

49+
if presence_event.type == 'enterSphere':
50+
sphere.present_people.append(user.cloud_id)
51+
52+
if presence_event.type == 'exitSphere':
53+
sphere.present_people.remove(user.cloud_id)
54+
4755
def update_data(self, data_change_event) -> None:
4856
"""
4957
Replace the current data with new data from the cloud after a change.

examples/asyncSwitchCrownstones.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
22
This is an example how to switch a crownstone using the crownstone python cloud lib.
33
4-
Last update by Ricardo Steijn on 15-5-2020
4+
Last update by Ricardo Steijn on 2-6-2020
55
"""
66
from crownstone_cloud.lib.cloud import CrownstoneCloud
77
import asyncio
@@ -21,4 +21,6 @@ async def main():
2121
for crownstone in sphere.crownstones:
2222
await crownstone.turn_on()
2323

24+
await cloud.close_session()
25+
2426
asyncio.run(main())

examples/syncSwitchCrownstones.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
22
This is an example how to switch a crownstone using the crownstone python cloud lib.
33
4-
Last update by Ricardo Steijn on 15-5-2020
4+
Last update by Ricardo Steijn on 2-6-2020
55
"""
66
from crownstone_cloud.lib.cloud import CrownstoneCloud
77

@@ -10,5 +10,7 @@
1010
cloud.initialize_sync()
1111

1212
# get a crownstone and turn it on
13-
crownstone = cloud.get_crownstone('awesomeCrownstone')
14-
crownstone.turn_on_sync()
13+
crownstone = cloud.get_crownstone('AwesomePassword')
14+
crownstone.turn_on_sync()
15+
16+
cloud.close_session_sync()

tests/test_cloud.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ def test_init(self):
3636
self.cloud = CrownstoneCloud('email', 'password', loop=self.test_loop)
3737
assert self.cloud.loop == self.test_loop
3838

39-
self.cloud = CrownstoneCloud('email', 'password', loop=self.test_loop, websession=self.test_websession)
40-
assert RequestHandler.websession == self.test_websession
41-
4239
async def test_initialize(self):
4340
# test init, only logging in when there's no access token
4441
with asynctest.patch.object(CrownstoneCloud, 'login') as login_mock:
@@ -115,7 +112,7 @@ async def test_data_structure(self, mock_request):
115112
mock_request.assert_awaited()
116113
# presence
117114
mock_request.return_value = presence_data
118-
await sphere.locations.update_presence()
115+
await sphere.locations.update_location_presence()
119116
mock_request.assert_awaited()
120117

121118
# test getting crownstone, users, locations by id & name

0 commit comments

Comments
 (0)