Designed for the Raspberry Pi Zero-W and Alexa
Copyright 2021 Janick Bergeron <[email protected]>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+-------+ +----------+ +---------+ +-----------+ +---------+
| Alexa | --> | Lambda | --> | AWS IoT | --> | Raspberry | --> | PM5 |
| Voice | | Function | | shadow | | Pi | | Monitor |
+-------+ +----------+ +---------+ +-----------+ +---------+
Make sure you have the right policies attached to the correct AWS roles and certificates!
In development.
I was originally going to keep this repository and project private, but after attempting to post a question about the BLE API in the Concept2 SDK Forum, my post was rejected because it "has the only purpose to advertise for a website or another product". In fact, I was asking if anyone had made any progress on the issues reported in that post and that post because I ran into the exact same problem.
Good news: I figured out what I was doing wrong.
Turns out you cannot read the PM5 BLE characteristics using the bleak.backends.client.BaseBleakClient::read_gatt_attr() method, except for the Device Information Service characteristics (UUIDs 0x0011 thru 0x0016). The response you'll receive by reading all other characteritics will have the correct structure (number of bytes, CSAFE framing, etc...) but the variable content will be junk. All other characteristics, including CSAFE command responses, must be read via a change notification handler.
I also had incorrectly implemented the co-routine necessary to use Bleak. Python was not giving any run-time errors, but calling regular subroutines and passing the async manager as argument appears to break things. The async patterns must be strictly followed.
- Discovers and connects to rower
- Receives updates from rowing service every half-seconds.
- Main screen design with updating rowing stats and status widget from PM5 state updates
- Alexa front-end to start app, program an X minutes or meters work-out or scheduled workout, cancel a work-out
- Free, duration, and distance-based workouts working, with auto-pause, resume, and stop
- Display
- Add target stroke, pace, and heart rate to display widgets
- Course map/plot widget based on target/estimated total distance
- Add pace boat to course map/plot
- Work-outs
- Program, then run a multi-splits work-out (e.g. warm-up and cool-down)
- Log workout
- User Profiles
- Scale work-out target parameters based on user profile data
- Update user profile (age, max heart rate, etc..) via Alexa
- Multi-User
- Python 3.6 or later (required by Bleak)
- Bleak
- aiotkinter
- AWSIoTPythonSDK
- matplotlib
- x11-server-utils ('xset' command to wake up sleeping screen)