Skip to main content

peat_btle/power/
mod.rs

1// Copyright (c) 2025-2026 (r)evolve - Revolve Team LLC
2// SPDX-License-Identifier: Apache-2.0
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Power Management for Peat-Lite
17//!
18//! Provides power-efficient radio scheduling and profile management
19//! for battery-constrained BLE devices.
20//!
21//! ## Overview
22//!
23//! This module implements the power management layer that enables
24//! Peat-Lite devices to achieve 20+ hour battery life on typical
25//! smartwatch hardware (300mAh battery).
26//!
27//! ## Key Components
28//!
29//! - **Power Profiles**: Predefined configurations balancing latency vs battery
30//! - **Radio Scheduler**: Coordinates scan, advertise, and sync activities
31//! - **Battery Awareness**: Auto-adjusts profile based on battery state
32//!
33//! ## Architecture
34//!
35//! ```text
36//! ┌────────────────────────────────────────────────────────┐
37//! │                    Application                          │
38//! │              (sync requests, alerts)                    │
39//! └─────────────────────┬──────────────────────────────────┘
40//!                       │
41//!                       ▼
42//! ┌────────────────────────────────────────────────────────┐
43//! │                 RadioScheduler                          │
44//! │  ┌──────────────┐  ┌────────────┐  ┌────────────────┐  │
45//! │  │ PowerProfile │  │   Pending  │  │   Battery      │  │
46//! │  │   Timing     │──│   Syncs    │──│   Monitor      │  │
47//! │  └──────────────┘  └────────────┘  └────────────────┘  │
48//! └─────────────────────┬──────────────────────────────────┘
49//!                       │
50//!                       ▼
51//! ┌────────────────────────────────────────────────────────┐
52//! │              BLE Radio Hardware                         │
53//! │         (scan, advertise, connect)                      │
54//! └────────────────────────────────────────────────────────┘
55//! ```
56//!
57//! ## Power Profiles
58//!
59//! | Profile | Duty Cycle | Battery Life | Use Case |
60//! |---------|------------|--------------|----------|
61//! | Aggressive | ~20% | ~6h | Emergency response |
62//! | Balanced | ~10% | ~12h | Active tracking |
63//! | **LowPower** | **~2%** | **~20h** | Normal operation |
64//!
65//! ## Usage
66//!
67//! ```ignore
68//! use peat_btle::power::{RadioScheduler, PowerProfile, SyncPriority};
69//! use peat_btle::NodeId;
70//!
71//! // Create scheduler with low-power profile
72//! let mut scheduler = RadioScheduler::with_profile(PowerProfile::LowPower);
73//!
74//! // Queue a normal sync
75//! scheduler.queue_sync(peer_id, SyncPriority::Normal, 100, current_time);
76//!
77//! // Main loop
78//! loop {
79//!     if let Some((event, time)) = scheduler.next_event(current_time) {
80//!         match event {
81//!             SchedulerEvent::StartScan => {
82//!                 radio.start_scan();
83//!                 scheduler.process_event(event, current_time);
84//!             }
85//!             SchedulerEvent::SyncNow => {
86//!                 if let Some(sync) = scheduler.next_pending_sync(current_time) {
87//!                     perform_sync(&sync);
88//!                     scheduler.complete_sync(current_time);
89//!                 }
90//!             }
91//!             SchedulerEvent::EnterSleep => {
92//!                 let sleep_time = scheduler.time_until_next_activity(current_time);
93//!                 mcu.sleep_ms(sleep_time);
94//!             }
95//!             _ => scheduler.process_event(event, current_time),
96//!         }
97//!     }
98//! }
99//! ```
100//!
101//! ## Critical Sync
102//!
103//! For urgent data (SOS alerts, medical emergencies), use `SyncPriority::Critical`:
104//!
105//! ```ignore
106//! // This bypasses normal scheduling and syncs immediately
107//! scheduler.queue_sync(peer_id, SyncPriority::Critical, data_size, current_time);
108//! ```
109//!
110//! ## Battery Auto-Adjustment
111//!
112//! The scheduler can automatically switch to lower power profiles as battery depletes:
113//!
114//! ```ignore
115//! scheduler.set_auto_adjust(true);
116//! scheduler.update_battery(BatteryState::new(15, false), current_time);
117//! // Automatically switches from Aggressive/Balanced to LowPower
118//! ```
119
120pub mod profile;
121pub mod scheduler;
122
123pub use profile::{BatteryState, PowerProfile, RadioTiming};
124pub use scheduler::{
125    PendingSync, RadioScheduler, RadioState, SchedulerConfig, SchedulerEvent, SchedulerStats,
126    SyncPriority,
127};