Skip to content

Commit 29dabb4

Browse files
authored
v0.4.1 (#6)
* Fixed refresh function * String cast for refresh * Added image refresh function, increased test coverage * Added a thumb dict function
1 parent 34befb2 commit 29dabb4

File tree

3 files changed

+156
-30
lines changed

3 files changed

+156
-30
lines changed

blinkpy.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import getpass
1818
import json
1919

20-
__version__ = '0.3.0'
20+
__version__ = '0.4.1'
2121

2222
BLINK_URL = 'immedia-semi.com'
2323
LOGIN_URL = 'https://prod.' + BLINK_URL + '/login'
@@ -186,8 +186,21 @@ def update(self, values):
186186
self._BATTERY = values['battery']
187187
self._NOTIFICATIONS = values['notifications']
188188

189+
def image_refresh(self):
190+
url = BASE_URL + '/homescreen'
191+
response = _request(url, headers=self._HEADER, type='get')['devices']
192+
for element in response:
193+
try:
194+
if str(element['device_id']) == self._ID:
195+
self._THUMB = BASE_URL + element['thumbnail'] + '.jpg'
196+
return self._THUMB
197+
except KeyError:
198+
pass
199+
return None
200+
189201
def image_to_file(self, path):
190-
response = _request(self._THUMB, headers=self._HEADER, stream=True, json=False)
202+
thumb = self.image_refresh()
203+
response = _request(thumb, headers=self._HEADER, stream=True, json=False)
191204
if response.status_code == 200:
192205
with open(path, 'wb') as f:
193206
for chunk in response:
@@ -215,6 +228,15 @@ def __init__(self, username=None, password=None):
215228
def cameras(self):
216229
return self._CAMERAS
217230

231+
@property
232+
def camera_thumbs(self):
233+
self.refresh()
234+
data = {}
235+
for name, camera in self._CAMERAS.items():
236+
data[name] = camera.thumbnail
237+
238+
return data
239+
218240
@property
219241
def id_table(self):
220242
return self._IDLOOKUP
@@ -287,7 +309,7 @@ def refresh(self):
287309
for name, camera in self._CAMERAS.items():
288310
for element in response:
289311
try:
290-
if element['id'] == camera.id:
312+
if str(element['device_id']) == camera.id:
291313
camera.update(element)
292314
except KeyError:
293315
pass

tests/test_blink_requests.py

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from unittest import mock
55
from blinkpy import LOGIN_URL
66
from blinkpy import BASE_URL
7+
import test_const as const
78

89
def mocked_requests_post(*args, **kwargs):
910
class MockPostResponse:
@@ -14,7 +15,7 @@ def json(self):
1415
return self.json_data
1516

1617
if args[0] == LOGIN_URL:
17-
return MockPostResponse({"region":{"test": "Notacountry"}, "authtoken":{"authtoken":"abcd1234"}}, 200)
18+
return MockPostResponse({"region":{const.REGION_ID: const.REGION}, "authtoken":{"authtoken":const.TOKEN}}, 200)
1819
elif args[0].split("/")[-1] == 'arm':
1920
return MockPostResponse({"armed":True}, 200)
2021
elif args[0].split("/")[-1] == 'disarm':
@@ -33,20 +34,9 @@ def json(self):
3334
return self.json_data
3435

3536
if args[0] == BASE_URL + '/networks':
36-
return MockGetResponse({'networks':[{"id":7777,"account_id":3333},{"nothing":"nothing"}]}, 200)
37+
return MockGetResponse({'networks':[{"id":const.NETWORK_ID,"account_id":const.ACCOUNT_ID},{"nothing":"nothing"}]}, 200)
3738
else:
38-
return MockGetResponse({'devices':[{'device_type':'camera','name':'test','device_id':123,'armed':False,'thumbnail':'/some/url','temp':65,'battery':3,'notifications':1},
39-
{'device_type':'camera','name':'test2','device_id':321,'armed':True,'thumbnail':'/some/new/url','temp':56,'battery':5,'notifications':0},
40-
{'device_type':'None'}
41-
],
42-
'events':[{'camera_id':123, 'type':'motion', 'video_url':'/some/dumb/location.mp4', 'created_at':'2017-01-01'},
43-
{'camera_id':321, 'type':'None'}
44-
],
45-
'syncmodule':{'name':'SyncName', 'status':'online'},
46-
'network':{'name':'Sync','armed':True, 'notifications':4}
47-
},
48-
200
49-
)
39+
return MockGetResponse(const.response, 200)
5040

5141

5242
return MockGetResponse({'message':'ERROR','code':404}, 404)
@@ -58,12 +48,12 @@ def test_blink_setup(self, mock_get, mock_post):
5848
blink = blinkpy.Blink(username='user',password='password')
5949
blink.setup_system()
6050

61-
self.assertEqual(blink.network_id, '7777')
62-
self.assertEqual(blink.account_id, '3333')
63-
self.assertEqual(blink.region, 'Notacountry')
64-
self.assertEqual(blink.region_id, 'test')
65-
self.assertEqual(blink.online, True)
66-
self.assertEqual(blink.arm, True)
51+
self.assertEqual(blink.network_id, str(const.NETWORK_ID))
52+
self.assertEqual(blink.account_id, str(const.ACCOUNT_ID))
53+
self.assertEqual(blink.region, const.REGION)
54+
self.assertEqual(blink.region_id, const.REGION_ID)
55+
self.assertEqual(blink.online, const.ISONLINE)
56+
self.assertEqual(blink.arm, const.ARMED)
6757

6858
@mock.patch('blinkpy.requests.post', side_effect=mocked_requests_post)
6959
@mock.patch('blinkpy.requests.get', side_effect=mocked_requests_get)
@@ -72,14 +62,39 @@ def test_blink_camera_setup_and_motion(self, mock_get, mock_post):
7262
blink.setup_system()
7363
blink.last_motion()
7464
for name, camera in blink.cameras.items():
75-
if camera.id == '123':
76-
self.assertEqual(name, 'test')
77-
self.assertEqual(camera.armed, False)
78-
self.assertEqual(camera.motion['video'], BASE_URL+'/some/dumb/location.mp4')
79-
elif camera.id == '321':
80-
self.assertEqual(name, 'test2')
81-
self.assertEqual(camera.armed, True)
65+
if camera.id == str(const.DEVICE_ID):
66+
self.assertEqual(name, const.CAMERA_NAME)
67+
self.assertEqual(camera.armed, const.ARMED)
68+
self.assertEqual(camera.motion['video'], BASE_URL + const.THUMB + '.mp4')
69+
elif camera.id == str(const.DEVICE_ID2):
70+
self.assertEqual(name, const.CAMERA_NAME2)
71+
self.assertEqual(camera.armed, const.ARMED2)
8272
self.assertEqual(len(camera.motion.keys()), 0)
8373
else:
8474
assert False is True
75+
76+
@mock.patch('blinkpy.requests.post', side_effect=mocked_requests_post)
77+
@mock.patch('blinkpy.requests.get', side_effect=mocked_requests_get)
78+
def test_blink_refresh(self, mock_get, mock_post):
79+
blink = blinkpy.Blink(username='user',password='password')
80+
blink.setup_system()
81+
const.response['devices'][0]['thumbnail'] = const.THUMB + const.THUMB2
82+
blink.refresh()
83+
for name, camera in blink.cameras.items():
84+
if camera.id == str(const.DEVICE_ID):
85+
self.assertEqual(camera.thumbnail, BASE_URL + const.THUMB + const.THUMB2 + '.jpg')
86+
elif camera.id == str(const.DEVICE_ID2):
87+
pass
88+
else:
89+
assert False is True
90+
91+
const.response['devices'][0]['thumbnail'] = 'new'
92+
blink.cameras[const.CAMERA_NAME].image_refresh()
93+
for name, camera in blink.cameras.items():
94+
if camera.id == str(const.DEVICE_ID):
95+
self.assertEqual(camera.thumbnail, BASE_URL + 'new' + '.jpg')
96+
elif camera.id == str(const.DEVICE_ID2):
97+
pass
98+
else:
99+
assert False is True
85100

tests/test_const.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
ISONLINE = True
2+
ARMED = True
3+
ARMED2 = False
4+
REGION_ID = 'test'
5+
REGION = 'Oceaniaeurasia'
6+
TOKEN = 'abcd1234$$@@'
7+
NETWORK_ID = 1337
8+
DEVICE_ID = 9876
9+
DEVICE_ID2 = 6789
10+
ACCOUNT_ID = 1234
11+
CAMERA_NAME = 'My Camera'
12+
CAMERA_NAME2 = 'Number 2'
13+
BATTERY = 3
14+
BATTERY2 = 1
15+
TEMP = 70
16+
TEMP2 = 66
17+
THUMB = '/url/camera/7777/clip'
18+
THUMB2 = '/url/camera/8888/clip'
19+
NOTIFS = 1
20+
NOTIFS2 = 1
21+
22+
if ISONLINE:
23+
ONLINE = 'online'
24+
else:
25+
ONLINE = 'offline'
26+
27+
28+
response = {'account': {'notifications': 1},
29+
'devices': [{'device_type': 'camera',
30+
'notifications': NOTIFS,
31+
'battery': BATTERY,
32+
'active': 'disabled',
33+
'errors': 0,
34+
'error_msg': '',
35+
'enabled': False,
36+
'temp': TEMP,
37+
'updated_at': '2017-01-27T03:14:24+00:00',
38+
'lfr_strength': 3,
39+
'armed': ARMED,
40+
'device_id': DEVICE_ID,
41+
'wifi_strength': 5,
42+
'warning': 0,
43+
'thumbnail': THUMB,
44+
'name': CAMERA_NAME,
45+
'status': 'done'},
46+
{'device_type': 'camera',
47+
'notifications': NOTIFS2,
48+
'battery': BATTERY2,
49+
'active': 'disabled',
50+
'errors': 0,
51+
'error_msg': '',
52+
'enabled': False,
53+
'temp': TEMP2,
54+
'updated_at': '2017-01-27T03:14:24+00:00',
55+
'lfr_strength': 3,
56+
'armed': ARMED2,
57+
'device_id': DEVICE_ID2,
58+
'wifi_strength': 5,
59+
'warning': 0,
60+
'thumbnail': THUMB2,
61+
'name': CAMERA_NAME2,
62+
'status': 'done'},
63+
{'updated_at': '2017-01-26T19:32:10+00:00',
64+
'device_type': 'sync_module',
65+
'notifications': 0,
66+
'device_id': 0000,
67+
'status':
68+
'online',
69+
'last_hb':
70+
'2017-01-27T03:14:49+00:00',
71+
'errors': 0,
72+
'error_msg': '',
73+
'warning': 0}],
74+
'network': {'armed': ARMED,
75+
'wifi_strength': 5,
76+
'warning': 0,
77+
'error_msg': '',
78+
'name': 'Blink',
79+
'notifications': NOTIFS,
80+
'status': 'ok'},
81+
'events': [{'camera_id':DEVICE_ID,
82+
'type':'motion',
83+
'video_url':THUMB + '.mp4',
84+
'created_at':'2017-01-01'},
85+
{'camera_id':DEVICE_ID2,
86+
'type':'None'}],
87+
'syncmodule':{'name':'SyncName',
88+
'status':ONLINE}}
89+

0 commit comments

Comments
 (0)