petsafe-api 3.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2020 Jordan Stremming
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,264 @@
1
+ Metadata-Version: 2.4
2
+ Name: petsafe-api
3
+ Version: 3.0.1
4
+ Summary: Provides ability to connect and control a PetSafe Smart Feed, Scoopfree, and Smart Door devices using the PetSafe API.
5
+ Home-page: https://github.com/ThomasHFWright/petsafe-api
6
+ Author: Jordan Stremming & Dominick Meglio & Thomas Wright
7
+ Author-email: thomas.h.f.wright@gmail.com
8
+ License: MIT
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: httpx
16
+ Requires-Dist: botocore
17
+ Dynamic: author
18
+ Dynamic: author-email
19
+ Dynamic: classifier
20
+ Dynamic: description
21
+ Dynamic: description-content-type
22
+ Dynamic: home-page
23
+ Dynamic: license
24
+ Dynamic: license-file
25
+ Dynamic: requires-dist
26
+ Dynamic: requires-python
27
+ Dynamic: summary
28
+
29
+ # petsafe-api
30
+ Connect and control PetSafe Smart Feed, ScoopFree, and Smart Door devices using the PetSafe API.
31
+
32
+ > **BREAKING CHANGE:** Version 2.0 uses the new PetSafe API.
33
+ > You will need to request new tokens.
34
+
35
+ > PetSafe will lock your account if you request data more often than once per 5 minutes.
36
+
37
+ ## Project rename
38
+ This repository is now named **petsafe-api** and the published package name is **petsafe-api** on PyPI.
39
+
40
+ > Import paths are unchanged: continue using `import petsafe` and `python -m petsafe`.
41
+
42
+ ## Acknowledgements
43
+ This project builds on the excellent prior work from the original developers:
44
+ - https://github.com/Techzune/petsafe_smartfeed
45
+ - https://github.com/dcmeglio/petsafe
46
+
47
+ Thank you to both projects for building the API integrations for existing feeder and ScoopFree functionality. This repository includes all of that previous work, with Smart Door API support added on top.
48
+
49
+ ## Installation
50
+ `pip install petsafe-api`
51
+
52
+ If installing from source code,
53
+ `python setup.py install`
54
+
55
+ ## Login tokens
56
+ You **must** use tokens to interact with the PetSafe Smart-Feed API.
57
+ There are two methods to retrieve tokens:
58
+
59
+ #### Get tokens using command line
60
+ 1. Execute `python -m petsafe [email_address]` to request an email code.
61
+ 2. Check your email for an email code from PetSafe.
62
+ 3. Enter your code to generate tokens.
63
+
64
+ #### Get tokens using Python
65
+ ```python
66
+ import petsafe as sf
67
+
68
+
69
+ # replace with your email address
70
+ client = sf.PetSafeClient(email="email@example.com")
71
+ client.request_code()
72
+
73
+ # check your email for a code
74
+ code = input("Enter email code: ")
75
+ token = client.request_tokens_from_code(code)
76
+
77
+ print("email:", client.email)
78
+ print("id_token:", client.id_token)
79
+ print("refresh_token:", client.refresh_token)
80
+ print("access_token:", client.access_token)
81
+ ```
82
+
83
+
84
+ ## Example usage
85
+ #### List feeders
86
+
87
+ ```python
88
+ import petsafe as sf
89
+
90
+ client = sf.PetSafeClient(email="email@example.com",
91
+ id_token="YOUR_ID_TOKEN",
92
+ refresh_token="YOUR_REFRESH_TOKEN",
93
+ access_token="YOUR_ACCESS_TOKEN")
94
+ devices = sf.devices.get_feeders(client)
95
+
96
+ # print all feeders
97
+ for device in devices:
98
+ print(device)
99
+
100
+ ```
101
+ #### Feed 1/8 cup at normal speed
102
+ ```python
103
+ import petsafe as sf
104
+
105
+ client = sf.PetSafeClient(email="email@example.com",
106
+ id_token="YOUR_ID_TOKEN",
107
+ refresh_token="YOUR_REFRESH_TOKEN",
108
+ access_token="YOUR_ACCESS_TOKEN")
109
+ devices = sf.devices.get_feeders(client)
110
+
111
+ # get the first feeder
112
+ feeder = devices[0]
113
+ feeder.feed(amount=1, slow_feed=False)
114
+
115
+ ```
116
+ #### Get current battery level (0 - 100)
117
+ ```python
118
+ import petsafe as sf
119
+
120
+ client = sf.PetSafeClient(email="email@example.com",
121
+ id_token="YOUR_ID_TOKEN",
122
+ refresh_token="YOUR_REFRESH_TOKEN",
123
+ access_token="YOUR_ACCESS_TOKEN")
124
+ devices = sf.devices.get_feeders(client)
125
+
126
+ # get the first feeder
127
+ feeder = devices[0]
128
+ print(feeder.battery_level)
129
+
130
+ ```
131
+ #### Get current food level
132
+ ```python
133
+ import petsafe as sf
134
+
135
+ client = sf.PetSafeClient(email="email@example.com",
136
+ id_token="YOUR_ID_TOKEN",
137
+ refresh_token="YOUR_REFRESH_TOKEN",
138
+ access_token="YOUR_ACCESS_TOKEN")
139
+ devices = sf.devices.get_feeders(client)
140
+
141
+ # get the first feeder
142
+ feeder = devices[0]
143
+ status = feeder.food_low_status
144
+
145
+ if status == 0:
146
+ print("Feeder has food.")
147
+ elif status == 1:
148
+ print("Feeder is low on food.")
149
+ elif status == 2:
150
+ print("Feeder is out of food.")
151
+
152
+ ```
153
+
154
+ ## SmartDoor controls
155
+ ```python
156
+ import asyncio
157
+
158
+ import petsafe as sf
159
+
160
+
161
+ async def main() -> None:
162
+ client = sf.PetSafeClient(
163
+ email="email@example.com",
164
+ id_token="YOUR_ID_TOKEN",
165
+ refresh_token="YOUR_REFRESH_TOKEN",
166
+ access_token="YOUR_ACCESS_TOKEN",
167
+ )
168
+
169
+ doors = await client.get_smartdoors()
170
+ door = doors[0]
171
+
172
+ # Manually lock the door and refresh its reported state
173
+ await door.lock()
174
+
175
+ # Switch back to Smart mode without forcing a refresh
176
+ await door.smart_mode(update_data=False)
177
+
178
+ # Or use the client helpers that return the updated door instance
179
+ updated = await client.manual_unlock_smartdoor(door.api_name)
180
+ print(updated.mode)
181
+
182
+
183
+ asyncio.run(main())
184
+ ```
185
+
186
+ # get litterboxes
187
+ ```python
188
+ import petsafe as sf
189
+
190
+ client = sf.PetSafeClient(email="email@example.com",
191
+ id_token="YOUR_ID_TOKEN",
192
+ refresh_token="YOUR_REFRESH_TOKEN",
193
+ access_token="YOUR_ACCESS_TOKEN")
194
+ devices = sf.devices.get_litterboxes(client)
195
+
196
+ # print all litterboxes
197
+ for device in devices:
198
+ print(device)
199
+
200
+ ```
201
+
202
+ # get litterbox activity
203
+ ```python
204
+ import petsafe as sf
205
+
206
+ client = sf.PetSafeClient(email="email@example.com",
207
+ id_token="YOUR_ID_TOKEN",
208
+ refresh_token="YOUR_REFRESH_TOKEN",
209
+ access_token="YOUR_ACCESS_TOKEN")
210
+ devices = sf.devices.get_litterboxes(client)
211
+
212
+ litterbox = devices[0]
213
+ print(litterbox.get_schedule())
214
+
215
+ ```
216
+
217
+ # rake the litterbox
218
+ ```python
219
+ import petsafe as sf
220
+
221
+ client = sf.PetSafeClient(email="email@example.com",
222
+ id_token="YOUR_ID_TOKEN",
223
+ refresh_token="YOUR_REFRESH_TOKEN",
224
+ access_token="YOUR_ACCESS_TOKEN")
225
+ devices = sf.devices.get_litterboxes(client)
226
+
227
+ litterbox = devices[0]
228
+ litterbox.rake()
229
+
230
+ ```
231
+
232
+ # modify the litterbox rake timer
233
+ ```python
234
+ import petsafe as sf
235
+
236
+ client = sf.PetSafeClient(email="email@example.com",
237
+ id_token="YOUR_ID_TOKEN",
238
+ refresh_token="YOUR_REFRESH_TOKEN",
239
+ access_token="YOUR_ACCESS_TOKEN")
240
+ devices = sf.devices.get_litterboxes(client)
241
+
242
+ litterbox = devices[0]
243
+ litterbox.modify_timer(15)
244
+
245
+ ```
246
+
247
+ # reset the litterbox rake count
248
+ ```python
249
+ import petsafe as sf
250
+
251
+ client = sf.PetSafeClient(email="email@example.com",
252
+ id_token="YOUR_ID_TOKEN",
253
+ refresh_token="YOUR_REFRESH_TOKEN",
254
+ access_token="YOUR_ACCESS_TOKEN")
255
+ devices = sf.devices.get_litterboxes(client)
256
+
257
+ litterbox = devices[0]
258
+ litterbox.reset()
259
+
260
+ ```
261
+
262
+ ## Contributing
263
+ All contributions are welcome.
264
+ Please, feel free to create a pull request!
@@ -0,0 +1,236 @@
1
+ # petsafe-api
2
+ Connect and control PetSafe Smart Feed, ScoopFree, and Smart Door devices using the PetSafe API.
3
+
4
+ > **BREAKING CHANGE:** Version 2.0 uses the new PetSafe API.
5
+ > You will need to request new tokens.
6
+
7
+ > PetSafe will lock your account if you request data more often than once per 5 minutes.
8
+
9
+ ## Project rename
10
+ This repository is now named **petsafe-api** and the published package name is **petsafe-api** on PyPI.
11
+
12
+ > Import paths are unchanged: continue using `import petsafe` and `python -m petsafe`.
13
+
14
+ ## Acknowledgements
15
+ This project builds on the excellent prior work from the original developers:
16
+ - https://github.com/Techzune/petsafe_smartfeed
17
+ - https://github.com/dcmeglio/petsafe
18
+
19
+ Thank you to both projects for building the API integrations for existing feeder and ScoopFree functionality. This repository includes all of that previous work, with Smart Door API support added on top.
20
+
21
+ ## Installation
22
+ `pip install petsafe-api`
23
+
24
+ If installing from source code,
25
+ `python setup.py install`
26
+
27
+ ## Login tokens
28
+ You **must** use tokens to interact with the PetSafe Smart-Feed API.
29
+ There are two methods to retrieve tokens:
30
+
31
+ #### Get tokens using command line
32
+ 1. Execute `python -m petsafe [email_address]` to request an email code.
33
+ 2. Check your email for an email code from PetSafe.
34
+ 3. Enter your code to generate tokens.
35
+
36
+ #### Get tokens using Python
37
+ ```python
38
+ import petsafe as sf
39
+
40
+
41
+ # replace with your email address
42
+ client = sf.PetSafeClient(email="email@example.com")
43
+ client.request_code()
44
+
45
+ # check your email for a code
46
+ code = input("Enter email code: ")
47
+ token = client.request_tokens_from_code(code)
48
+
49
+ print("email:", client.email)
50
+ print("id_token:", client.id_token)
51
+ print("refresh_token:", client.refresh_token)
52
+ print("access_token:", client.access_token)
53
+ ```
54
+
55
+
56
+ ## Example usage
57
+ #### List feeders
58
+
59
+ ```python
60
+ import petsafe as sf
61
+
62
+ client = sf.PetSafeClient(email="email@example.com",
63
+ id_token="YOUR_ID_TOKEN",
64
+ refresh_token="YOUR_REFRESH_TOKEN",
65
+ access_token="YOUR_ACCESS_TOKEN")
66
+ devices = sf.devices.get_feeders(client)
67
+
68
+ # print all feeders
69
+ for device in devices:
70
+ print(device)
71
+
72
+ ```
73
+ #### Feed 1/8 cup at normal speed
74
+ ```python
75
+ import petsafe as sf
76
+
77
+ client = sf.PetSafeClient(email="email@example.com",
78
+ id_token="YOUR_ID_TOKEN",
79
+ refresh_token="YOUR_REFRESH_TOKEN",
80
+ access_token="YOUR_ACCESS_TOKEN")
81
+ devices = sf.devices.get_feeders(client)
82
+
83
+ # get the first feeder
84
+ feeder = devices[0]
85
+ feeder.feed(amount=1, slow_feed=False)
86
+
87
+ ```
88
+ #### Get current battery level (0 - 100)
89
+ ```python
90
+ import petsafe as sf
91
+
92
+ client = sf.PetSafeClient(email="email@example.com",
93
+ id_token="YOUR_ID_TOKEN",
94
+ refresh_token="YOUR_REFRESH_TOKEN",
95
+ access_token="YOUR_ACCESS_TOKEN")
96
+ devices = sf.devices.get_feeders(client)
97
+
98
+ # get the first feeder
99
+ feeder = devices[0]
100
+ print(feeder.battery_level)
101
+
102
+ ```
103
+ #### Get current food level
104
+ ```python
105
+ import petsafe as sf
106
+
107
+ client = sf.PetSafeClient(email="email@example.com",
108
+ id_token="YOUR_ID_TOKEN",
109
+ refresh_token="YOUR_REFRESH_TOKEN",
110
+ access_token="YOUR_ACCESS_TOKEN")
111
+ devices = sf.devices.get_feeders(client)
112
+
113
+ # get the first feeder
114
+ feeder = devices[0]
115
+ status = feeder.food_low_status
116
+
117
+ if status == 0:
118
+ print("Feeder has food.")
119
+ elif status == 1:
120
+ print("Feeder is low on food.")
121
+ elif status == 2:
122
+ print("Feeder is out of food.")
123
+
124
+ ```
125
+
126
+ ## SmartDoor controls
127
+ ```python
128
+ import asyncio
129
+
130
+ import petsafe as sf
131
+
132
+
133
+ async def main() -> None:
134
+ client = sf.PetSafeClient(
135
+ email="email@example.com",
136
+ id_token="YOUR_ID_TOKEN",
137
+ refresh_token="YOUR_REFRESH_TOKEN",
138
+ access_token="YOUR_ACCESS_TOKEN",
139
+ )
140
+
141
+ doors = await client.get_smartdoors()
142
+ door = doors[0]
143
+
144
+ # Manually lock the door and refresh its reported state
145
+ await door.lock()
146
+
147
+ # Switch back to Smart mode without forcing a refresh
148
+ await door.smart_mode(update_data=False)
149
+
150
+ # Or use the client helpers that return the updated door instance
151
+ updated = await client.manual_unlock_smartdoor(door.api_name)
152
+ print(updated.mode)
153
+
154
+
155
+ asyncio.run(main())
156
+ ```
157
+
158
+ # get litterboxes
159
+ ```python
160
+ import petsafe as sf
161
+
162
+ client = sf.PetSafeClient(email="email@example.com",
163
+ id_token="YOUR_ID_TOKEN",
164
+ refresh_token="YOUR_REFRESH_TOKEN",
165
+ access_token="YOUR_ACCESS_TOKEN")
166
+ devices = sf.devices.get_litterboxes(client)
167
+
168
+ # print all litterboxes
169
+ for device in devices:
170
+ print(device)
171
+
172
+ ```
173
+
174
+ # get litterbox activity
175
+ ```python
176
+ import petsafe as sf
177
+
178
+ client = sf.PetSafeClient(email="email@example.com",
179
+ id_token="YOUR_ID_TOKEN",
180
+ refresh_token="YOUR_REFRESH_TOKEN",
181
+ access_token="YOUR_ACCESS_TOKEN")
182
+ devices = sf.devices.get_litterboxes(client)
183
+
184
+ litterbox = devices[0]
185
+ print(litterbox.get_schedule())
186
+
187
+ ```
188
+
189
+ # rake the litterbox
190
+ ```python
191
+ import petsafe as sf
192
+
193
+ client = sf.PetSafeClient(email="email@example.com",
194
+ id_token="YOUR_ID_TOKEN",
195
+ refresh_token="YOUR_REFRESH_TOKEN",
196
+ access_token="YOUR_ACCESS_TOKEN")
197
+ devices = sf.devices.get_litterboxes(client)
198
+
199
+ litterbox = devices[0]
200
+ litterbox.rake()
201
+
202
+ ```
203
+
204
+ # modify the litterbox rake timer
205
+ ```python
206
+ import petsafe as sf
207
+
208
+ client = sf.PetSafeClient(email="email@example.com",
209
+ id_token="YOUR_ID_TOKEN",
210
+ refresh_token="YOUR_REFRESH_TOKEN",
211
+ access_token="YOUR_ACCESS_TOKEN")
212
+ devices = sf.devices.get_litterboxes(client)
213
+
214
+ litterbox = devices[0]
215
+ litterbox.modify_timer(15)
216
+
217
+ ```
218
+
219
+ # reset the litterbox rake count
220
+ ```python
221
+ import petsafe as sf
222
+
223
+ client = sf.PetSafeClient(email="email@example.com",
224
+ id_token="YOUR_ID_TOKEN",
225
+ refresh_token="YOUR_REFRESH_TOKEN",
226
+ access_token="YOUR_ACCESS_TOKEN")
227
+ devices = sf.devices.get_litterboxes(client)
228
+
229
+ litterbox = devices[0]
230
+ litterbox.reset()
231
+
232
+ ```
233
+
234
+ ## Contributing
235
+ All contributions are welcome.
236
+ Please, feel free to create a pull request!
@@ -0,0 +1,2 @@
1
+ from . import devices, general, pets
2
+ from .client import PetSafeClient
@@ -0,0 +1,36 @@
1
+ import sys
2
+ import argparse
3
+
4
+ from petsafe import PetSafeClient
5
+
6
+ # create parser for arguments
7
+ parser = argparse.ArgumentParser(
8
+ usage="python -m petsafe email [-t email_code]"
9
+ )
10
+ parser.add_argument("email", help="account email address")
11
+
12
+ # if no arguments specified, show help
13
+ if len(sys.argv) < 2:
14
+ parser.print_help()
15
+ sys.exit(1)
16
+
17
+ # parse for arguments
18
+ args = parser.parse_args()
19
+
20
+ client = PetSafeClient(email=args.email)
21
+ client.request_code()
22
+ print("Code requested, please check your email.")
23
+ print("")
24
+
25
+ code = input("Enter email code: ")
26
+ client.request_tokens_from_code(code)
27
+
28
+ print("")
29
+ print("IdToken:")
30
+ print(client.id_token)
31
+ print("")
32
+ print("AccessToken:")
33
+ print(client.access_token)
34
+ print("")
35
+ print("RefreshToken:")
36
+ print(client.refresh_token)