19
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
20
# SOFTWARE.
21
21
import json
22
- import pkg_resources
23
22
import platform
23
+ import pkg_resources
24
24
# import logging
25
25
26
26
import requests
@@ -52,21 +52,50 @@ def __init__(self, username, key, proxies=None, base_url='https://io.adafruit.co
52
52
self .username = username
53
53
self .key = key
54
54
self .proxies = proxies
55
- # self.logger = logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
55
+ # self.logger = logging.basicConfig(level=logging.DEBUG,
56
+ # format='%(asctime)s - %(levelname)s - %(message)s')
56
57
57
58
# Save URL without trailing slash as it will be added later when
58
59
# constructing the path.
59
60
self .base_url = base_url .rstrip ('/' )
60
61
62
+ @staticmethod
63
+ def to_red (data ):
64
+ """Hex color feed to red channel.
65
+ :param int data: Color value, in hexadecimal.
66
+ """
67
+ return ((int (data [1 ], 16 ))* 16 ) + int (data [2 ], 16 )
61
68
62
- def _compose_url (self , path , is_time = None ):
63
- if is_time : # return a call to https://io.adafruit.com/api/v2/time/{unit}
64
- return '{0}/api/{1}/{2}' .format (self .base_url , 'v2' , path )
65
- else :
66
- return '{0}/api/{1}/{2}/{3}' .format (self .base_url , 'v2' , self .username , path )
69
+ @staticmethod
70
+ def to_green (data ):
71
+ """Hex color feed to green channel.
72
+ :param int data: Color value, in hexadecimal.
73
+ """
74
+ return (int (data [3 ], 16 ) * 16 ) + int (data [4 ], 16 )
67
75
76
+ @staticmethod
77
+ def to_blue (data ):
78
+ """Hex color feed to blue channel.
79
+ :param int data: Color value, in hexadecimal.
80
+ """
81
+ return (int (data [5 ], 16 ) * 16 ) + int (data [6 ], 16 )
82
+
83
+ @staticmethod
84
+ def _headers (given ):
85
+ headers = default_headers .copy ()
86
+ headers .update (given )
87
+ return headers
88
+
89
+ @staticmethod
90
+ def _create_payload (value , metadata ):
91
+ if metadata is not None :
92
+ payload = Data (value = value , lat = metadata ['lat' ], lon = metadata ['lon' ],
93
+ ele = metadata ['ele' ], created_at = metadata ['created_at' ])
94
+ return payload
95
+ return Data (value = value )
68
96
69
- def _handle_error (self , response ):
97
+ @staticmethod
98
+ def _handle_error (response ):
70
99
# Throttling Error
71
100
if response .status_code == 429 :
72
101
raise ThrottlingError ()
@@ -78,10 +107,10 @@ def _handle_error(self, response):
78
107
raise RequestError (response )
79
108
# Else do nothing if there was no error.
80
109
81
- def _headers (self , given ):
82
- headers = default_headers . copy ()
83
- headers . update ( given )
84
- return headers
110
+ def _compose_url (self , path , is_time = None ):
111
+ if is_time : # return a call to https://io.adafruit.com/api/v2/time/{unit}
112
+ return '{0}/api/{1}/{2}' . format ( self . base_url , 'v2' , path )
113
+ return '{0}/api/{1}/{2}/{3}' . format ( self . base_url , 'v2' , self . username , path )
85
114
86
115
def _get (self , path , is_time = None ):
87
116
response = requests .get (self ._compose_url (path , is_time ),
@@ -90,8 +119,7 @@ def _get(self, path, is_time=None):
90
119
self ._handle_error (response )
91
120
if not is_time :
92
121
return response .json ()
93
- else : # time doesn't need to serialize into json, just return text
94
- return response .text
122
+ return response .text
95
123
96
124
def _post (self , path , data ):
97
125
response = requests .post (self ._compose_url (path ),
@@ -105,20 +133,28 @@ def _post(self, path, data):
105
133
def _delete (self , path ):
106
134
response = requests .delete (self ._compose_url (path ),
107
135
headers = self ._headers ({'X-AIO-Key' : self .key ,
108
- 'Content-Type' : 'application/json' }),
136
+ 'Content-Type' : 'application/json' }),
109
137
proxies = self .proxies )
110
138
self ._handle_error (response )
111
139
112
140
# Data functionality.
113
- def send_data (self , feed , value ):
141
+ def send_data (self , feed , value , metadata = None , precision = None ):
114
142
"""Helper function to simplify adding a value to a feed. Will append the
115
143
specified value to the feed identified by either name, key, or ID.
116
144
Returns a Data instance with details about the newly appended row of data.
117
145
Note that send_data now operates the same as append.
118
146
:param string feed: Name/Key/ID of Adafruit IO feed.
119
147
:param string value: Value to send.
148
+ :param dict metadata: Optional metadata associated with the value.
149
+ :param int precision: Optional amount of precision points to send.
120
150
"""
121
- return self .create_data (feed , Data (value = value ))
151
+ if precision :
152
+ try :
153
+ value = round (value , precision )
154
+ except NotImplementedError :
155
+ raise NotImplementedError ("Using the precision kwarg requires a float value" )
156
+ payload = self ._create_payload (value , metadata )
157
+ return self .create_data (feed , payload )
122
158
123
159
send = send_data
124
160
@@ -144,42 +180,32 @@ def append(self, feed, value):
144
180
"""
145
181
return self .create_data (feed , Data (value = value ))
146
182
147
- def send_location_data (self , feed , lat , lon , ele , value = None ):
148
- """Sends locational data to a feed.
149
- :param string feed: Name/Key/ID of Adafruit IO feed.
150
- :param int lat: Latitude.
151
- :param int lon: Longitude.
152
- :param int ele: Elevation.
153
- :param int value: Optional value to send, defaults to None.
154
- """
155
- return self .create_data (feed , Data (value = value ,lat = lat , lon = lon , ele = ele ))
156
-
157
183
def receive_time (self , time ):
158
184
"""Returns the time from the Adafruit IO server.
159
185
:param string time: Time to be returned: `millis`, `seconds`, `ISO-8601`.
160
186
"""
161
187
timepath = "time/{0}" .format (time )
162
188
return self ._get (timepath , is_time = True )
163
-
189
+
164
190
def receive_weather (self , weather_id = None ):
165
191
"""Adafruit IO Weather Service, Powered by Dark Sky
166
192
:param int id: optional ID for retrieving a specified weather record.
167
193
"""
168
194
if weather_id :
169
- weather_path = "integrations/weather/{0}" .format (weather_id )
195
+ weather_path = "integrations/weather/{0}" .format (weather_id )
170
196
else :
171
- weather_path = "integrations/weather"
197
+ weather_path = "integrations/weather"
172
198
return self ._get (weather_path )
173
-
174
- def receive_random (self , id = None ):
199
+
200
+ def receive_random (self , randomizer_id = None ):
175
201
"""Access to Adafruit IO's Random Data
176
202
service.
177
- :param int id : optional ID for retrieving a specified randomizer.
203
+ :param int randomizer_id : optional ID for retrieving a specified randomizer.
178
204
"""
179
- if id :
180
- random_path = "integrations/words/{0}" .format (id )
205
+ if randomizer_id :
206
+ random_path = "integrations/words/{0}" .format (randomizer_id )
181
207
else :
182
- random_path = "integrations/words"
208
+ random_path = "integrations/words"
183
209
return self ._get (random_path )
184
210
185
211
def receive (self , feed ):
@@ -191,7 +217,7 @@ def receive(self, feed):
191
217
return Data .from_dict (self ._get (path ))
192
218
193
219
def receive_next (self , feed ):
194
- """Retrieve the next unread value from the specified feed. Returns a Data
220
+ """Retrieve the next unread value from the specified feed. Returns a Data
195
221
instance whose value property holds the retrieved value.
196
222
:param string feed: Name/Key/ID of Adafruit IO feed.
197
223
"""
@@ -215,16 +241,15 @@ def data(self, feed, data_id=None):
215
241
if data_id is None :
216
242
path = "feeds/{0}/data" .format (feed )
217
243
return list (map (Data .from_dict , self ._get (path )))
218
- else :
219
- path = "feeds/{0}/data/{1}" .format (feed , data_id )
220
- return Data .from_dict (self ._get (path ))
244
+ path = "feeds/{0}/data/{1}" .format (feed , data_id )
245
+ return Data .from_dict (self ._get (path ))
221
246
222
247
def create_data (self , feed , data ):
223
248
"""Create a new row of data in the specified feed.
224
- Returns a Data instance with details about the newly
249
+ Returns a Data instance with details about the newly
225
250
appended row of data.
226
251
:param string feed: Name/Key/ID of Adafruit IO feed.
227
- :param Data data: Instance of the Data class. Must have a value property set.
252
+ :param Data data: Instance of the Data class. Must have a value property set.
228
253
"""
229
254
path = "feeds/{0}/data" .format (feed )
230
255
return Data .from_dict (self ._post (path , data ._asdict ()))
@@ -237,24 +262,6 @@ def delete(self, feed, data_id):
237
262
path = "feeds/{0}/data/{1}" .format (feed , data_id )
238
263
self ._delete (path )
239
264
240
- def toRed (self , data ):
241
- """Hex color feed to red channel.
242
- :param int data: Color value, in hexadecimal.
243
- """
244
- return ((int (data [1 ], 16 ))* 16 ) + int (data [2 ], 16 )
245
-
246
- def toGreen (self , data ):
247
- """Hex color feed to green channel.
248
- :param int data: Color value, in hexadecimal.
249
- """
250
- return (int (data [3 ], 16 ) * 16 ) + int (data [4 ], 16 )
251
-
252
- def toBlue (self , data ):
253
- """Hex color feed to blue channel.
254
- :param int data: Color value, in hexadecimal.
255
- """
256
- return (int (data [5 ], 16 ) * 16 ) + int (data [6 ], 16 )
257
-
258
265
# feed functionality.
259
266
def feeds (self , feed = None ):
260
267
"""Retrieve a list of all feeds, or the specified feed. If feed is not
@@ -264,9 +271,8 @@ def feeds(self, feed=None):
264
271
if feed is None :
265
272
path = "feeds"
266
273
return list (map (Feed .from_dict , self ._get (path )))
267
- else :
268
- path = "feeds/{0}" .format (feed )
269
- return Feed .from_dict (self ._get (path ))
274
+ path = "feeds/{0}" .format (feed )
275
+ return Feed .from_dict (self ._get (path ))
270
276
271
277
def create_feed (self , feed ):
272
278
"""Create the specified feed.
@@ -290,9 +296,8 @@ def groups(self, group=None):
290
296
if group is None :
291
297
path = "groups/"
292
298
return list (map (Group .from_dict , self ._get (path )))
293
- else :
294
- path = "groups/{0}" .format (group )
295
- return Group .from_dict (self ._get (path ))
299
+ path = "groups/{0}" .format (group )
300
+ return Group .from_dict (self ._get (path ))
296
301
297
302
def create_group (self , group ):
298
303
"""Create the specified group.
@@ -306,4 +311,4 @@ def delete_group(self, group):
306
311
:param string group: Name/Key/ID of Adafruit IO Group.
307
312
"""
308
313
path = "groups/{0}" .format (group )
309
- self ._delete (path )
314
+ self ._delete (path )
0 commit comments