### Start WiFi Protected Setup (WPS)
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/wifi.md
Initiates a WPS connection process. Requires a `WpsConfig` parameter to configure the WPS session.
```rust
fn start_wps(&mut self, config: &WpsConfig) -> Result<(), EspError>
```
--------------------------------
### Start HTTP Server
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/README.md
Shows how to create a basic HTTP server that responds to GET requests on the root path with a simple HTML message.
```rust
use esp_idf_svc::http::server::{Configuration, EspHttpServer, Method};
let mut server = EspHttpServer::new(&Configuration::default())?;
server.fn_handler("/", Method::Get, |request| {
request
.into_ok_response()?
.write_all(b"
Hello!")
})?;
```
--------------------------------
### Web Server with mDNS Setup
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md
Example of setting up mDNS for a web server. This involves initializing mDNS, setting a hostname and instance name, creating an HTTP service, and configuring the HTTP server. The service is then accessible via its .local domain.
```rust
use esp_idf_svc::mdns::EspMdns;
use esp_idf_svc::http::server::{EspHttpServer, Configuration, Method};
// Setup mDNS
let mut mdns = EspMdns::new()?;
mdns.set_hostname("esp32webserver")?;
mdns.set_instance_name("My ESP32 Web Server")?;
// Create HTTP service
let mut service = mdns.create_service("http", "tcp", 80)?;
service.set_properties(&[
("path", "/"),
("version", "1.0"),
])?;
// Setup HTTP server
let mut server = EspHttpServer::new(&Configuration::default())?;
server.fn_handler("/", Method::Get, |request| {
request
.into_ok_response()?
.write_all(b"Hello from mDNS!")
})?;
// Now accessible at: http://esp32webserver.local
```
--------------------------------
### Internal Ethernet Initialization Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ethernet.md
Example of initializing and starting the internal Ethernet driver on an ESP32. Ensure the `peripheral` variable is correctly defined in your scope.
```rust
use esp_idf_svc::eth::{EthDriver, EthConfiguration, EthInterface, EthRmiiClkConfig, EthClockMode};
use esp_idf_svc::eventloop::EspSystemEventLoop;
let sysloop = EspSystemEventLoop::take()?;
let config = EthConfiguration {
interface: EthInterface::Rmii(EthRmiiClkConfig {
clock_mode: EthClockMode::GPIO0Out,
clock_gpio: None,
}),
..Default::default()
};
let mut eth_driver = EthDriver::new(
peripheral,
&config,
sysloop,
)?;
eth_driver.start()?;
```
--------------------------------
### Basic HTTP Server with GET and POST Handlers
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-server.md
This snippet demonstrates how to set up an HTTP server with basic GET and POST handlers. It includes examples for serving HTML content and processing POST request payloads. Ensure the `esp-idf-svc` crate is included in your project dependencies.
```rust
use esp_idf_svc::http::server::{Configuration, EspHttpServer, Method};
fn main() -> anyhow::Result<()> {
let mut server = EspHttpServer::new(&Configuration {
http_port: 8080,
max_uri_handlers: 4,
..Default::default()
})?;
// GET handler
server.fn_handler("/", Method::Get, |request| {
request
.into_ok_response()?
.write_all(b"Hello from ESP32!")
})?;
// POST handler
server.fn_handler("/submit", Method::Post, |mut request| {
let mut buffer = [0; 512];
let len = request.read(&mut buffer)?;
let payload = &buffer[..len];
let response = request.into_ok_response()?;
response.write_all(b"Received ")?;
response.write_all(payload)?;
Ok(())
})?;
// API handler with custom status
server.fn_handler("/api/status", Method::Get, |request| {
let mut response = request.into_response(200)?;
response.set_header("Content-Type", "application/json")?;
response.write_all(b"{\"status\":\"ok\"}")
})?;
// Keep server running
std::thread::sleep(std::time::Duration::from_secs(u64::MAX));
Ok(())
}
```
--------------------------------
### Typical partitions.csv Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md
An example of a typical `partitions.csv` file format used for defining device partitions.
```text
Name Type SubType Offset Size Flags
nvs data nvs 0x9000 0x6000
phy_init data phy 0xf000 0x1000
factory app factory 0x10000 0x140000
ota_data data ota 0x150000 0x2000
ota_0 app ota_0 0x152000 0x140000
ota_1 app ota_1 0x292000 0x140000
spiffs data spiffs 0x3d2000 0x2e000
```
--------------------------------
### HTTP Server Handler Examples
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-server.md
Demonstrates registering both a static HTML handler for GET requests and a data processing handler for POST requests.
```rust
let mut server = EspHttpServer::new(&Configuration::default())?;
server.fn_handler("/index.html", Method::Get, |request| {
request
.into_ok_response()?
.write_all(b"Hello world!")
})?;
server.fn_handler("/api/data", Method::Post, |mut request| {
let mut buf = [0; 256];
let size = request.read(&mut buf)?;
let body = std::str::from_utf8(&buf[..size])?;
// Process body...
request.into_ok_response()?.write_all(b"OK")
})?;
```
--------------------------------
### Build and Flash Example with cargo-espflash
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/README.md
This command demonstrates how to build and flash a Wi-Fi example to an ESP32-C3 using cargo-espflash. Adjust the MCU and target for your specific ESP32 device.
```sh
$ MCU=esp32c3 cargo espflash flash --target riscv32imc-esp-espidf --example wifi --monitor
```
--------------------------------
### EspHttpServer::new
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-server.md
Creates and starts a new HTTP server with the given configuration. The server automatically starts on creation and stops on drop.
```APIDOC
## EspHttpServer::new
### Description
Creates and starts a new HTTP server with the given configuration. The server automatically starts on creation and stops on drop.
### Signature
```rust
pub fn new(config: &Configuration) -> Result
```
### Parameters
#### Path Parameters
- **config** (`&Configuration`) - Required - Server configuration
```
--------------------------------
### Async One-Shot Timer Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md
Example demonstrating how to use an asynchronous one-shot timer with EspAsyncTimer.
```APIDOC
### Async One-Shot
```rust
use esp_idf_svc::timer::EspAsyncTimer;
use std::time::Duration;
async fn wait_example() -> Result<(), EspError> {
let mut timer = EspAsyncTimer::new()?;
println!("Waiting...");
timer.after(Duration::from_secs(1)).await?;
println!("Done!");
Ok(())
}
```
```
--------------------------------
### Synchronous One-Shot Timer Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md
Example demonstrating how to create and use a synchronous one-shot timer using EspTimerService.
```APIDOC
### Synchronous One-Shot
```rust
use esp_idf_svc::timer::EspTimerService;
use std::time::Duration;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
let timer_service = EspTimerService::new()?;
let fired = Arc::new(AtomicBool::new(false));
let fired_clone = fired.clone();
let timer = timer_service.create(move || {
fired_clone.store(true, Ordering::Release);
})?;
timer.after(Duration::from_millis(500))?;
std::thread::sleep(Duration::from_secs(1));
assert!(fired.load(Ordering::Acquire));
```
```
--------------------------------
### WifiDriver::start
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/wifi.md
Starts the WiFi driver, initiating its operation.
```APIDOC
## WifiDriver::start
### Description
Starts the WiFi driver, initiating its operation. This is equivalent to `esp_wifi_start()`.
### Method
`start`
### Returns
`Result<(), EspError>` - Success or error.
```
--------------------------------
### Example: Handling WiFi Connection Events
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/eventloop.md
Demonstrates how to subscribe to WiFi events and handle connection and disconnection notifications. The subscription is automatically managed and cleaned up.
```rust
use esp_idf_svc::eventloop::EspSystemEventLoop;
use esp_idf_svc::wifi::WifiEvent;
let sysloop = EspSystemEventLoop::take()?;
let subscription = sysloop.subscribe::(|event: WifiEvent| {
match event {
WifiEvent::StaConnected(_) => println!("Connected!"),
WifiEvent::StaDisconnected(_) => println!("Disconnected"),
_ => {}
}
})?;
// Subscription automatically unsubscribes when dropped
drop(subscription);
```
--------------------------------
### Rust MQTT Client Configuration Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/configuration.md
Configure MQTT client settings such as client ID, keep-alive interval, reconnect timeout, username, password, and LWT message. This example uses default values for other settings.
```rust
use esp_idf_svc::mqtt::client::{MqttClientConfiguration, LwtConfiguration, QoS};
use std::time::Duration;
let config = MqttClientConfiguration {
client_id: Some("esp32-device-01"),
keep_alive_interval: Some(Duration::from_secs(60)),
reconnect_timeout: Some(Duration::from_secs(10)),
username: Some("mqtt_user"),
password: Some("mqtt_pass"),
lwt: Some(LwtConfiguration {
topic: "devices/esp32/status",
payload: b"offline",
qos: QoS::AtMostOnce,
retain: true,
}),
..Default::default()
};
```
--------------------------------
### Full MQTT Client Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mqtt.md
Demonstrates connecting to an MQTT broker, configuring client options, subscribing to a topic, publishing a message, and handling incoming events in a separate thread.
```rust
use esp_idf_svc::mqtt::client::*
use std::time::Duration;
let mqtt_config = MqttClientConfiguration {
client_id: Some("esp32-client"),
keep_alive_interval: Some(Duration::from_secs(30)),
reconnect_timeout: Some(Duration::from_secs(10)),
username: Some("user"),
password: Some("pass"),
..Default::default()
};
let (mut client, mut connection) = EspMqttClient::new(
"mqtt://broker.mosquitto.org",
&mqtt_config,
|msg| {
match msg.payload() {
EventPayload::Connected(_) => println!("Connected"),
EventPayload::Received(data) => {
println!("Topic: {}, Data: {:?}", data.topic(), data.data());
}
EventPayload::Disconnected(_) => println!("Disconnected"),
_ => {}
}
Ok(())
}
)?;
// Subscribe to topic
client.subscribe("home/temperature", QoS::AtLeastOnce)?;
// Publish message
client.publish(
"home/status",
QoS::AtMostOnce,
true,
b"online"
)?;
// Handle events
std::thread::spawn(move || {
while let Ok(msg) = connection.recv() {
match msg {
Some(event) => println!("Event: {:?}", event),
None => break,
}
}
});
```
--------------------------------
### EthDriver Start Method
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ethernet.md
Starts the Ethernet interface. Returns a Result indicating success or an error.
```rust
pub fn start(&mut self) -> Result<(), EspError>
```
--------------------------------
### Async Periodic Timer Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md
Example demonstrating how to use an asynchronous periodic timer with EspAsyncTimer.
```APIDOC
### Async Periodic
```rust
use esp_idf_svc::timer::EspAsyncTimer;
use std::time::Duration;
async fn periodic_example() -> Result<(), EspError> {
let mut timer = EspAsyncTimer::new()?;
timer.every(Duration::from_millis(100))?;
for i in 0..10 {
timer.tick().await?;
println!("Tick {}", i);
}
Ok(())
}
```
```
--------------------------------
### Example: Using a Custom NVS Partition
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md
Shows how to initialize a custom NVS partition by specifying its name and then use it to store key-value pairs within a specific namespace.
```rust
use esp_idf_svc::nvs::{EspNvsPartition, NvsCustom};
let nvs = EspNvsPartition::::take("custom_partition")?;
let mut storage = nvs.data::("settings")?;
storage.put("wifi_ssid", "MyNetwork")?;
storage.put("wifi_password", "SecurePass")?;
```
--------------------------------
### Synchronous Periodic Timer Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md
Example demonstrating how to create and use a synchronous periodic timer using EspTimerService.
```APIDOC
### Synchronous Periodic
```rust
use esp_idf_svc::timer::EspTimerService;
use std::time::Duration;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
let timer_service = EspTimerService::new()?;
let count = Arc::new(AtomicU32::new(0));
let count_clone = count.clone();
let timer = timer_service.create(move || {
count_clone.fetch_add(1, Ordering::AcqRel);
})?;
timer.every(Duration::from_millis(10))?;
std::thread::sleep(Duration::from_millis(100));
timer.cancel()?;
let final_count = count.load(Ordering::Acquire);
assert!(final_count >= 9); // ~10 ticks in 100ms
```
```
--------------------------------
### Example: Using the Default NVS Partition
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md
Demonstrates how to initialize the default NVS partition, create a namespace handle, store, retrieve, and delete values using the StorageBase trait.
```rust
use esp_idf_svc::nvs::{EspDefaultNvsPartition, NvsDefault};
use embedded_svc::storage::StorageBase;
// Initialize default NVS
let nvs = EspDefaultNvsPartition::take_default()?;
// Create a namespace handle
let mut storage = nvs.data::("myapp")?;
// Store a value
storage.put("counter", 42)?;
// Retrieve it
let value: u32 = storage.get("counter")?.unwrap_or(0);
assert_eq!(value, 42);
// Check existence
if storage.contains("counter")? {
println!("Counter exists");
}
// Delete
storage.remove("counter")?;
```
--------------------------------
### Example: Using an Encrypted NVS Partition
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md
Demonstrates initializing an encrypted NVS partition, optionally providing a key storage partition. This is suitable for sensitive data.
```rust
use esp_idf_svc::nvs::{EspNvsPartition, NvsEncrypted};
// Creates keys if they don't exist
let nvs = EspNvsPartition::::take_with_key(
"nvs_encrypted",
Some("nvs_keys")
)?;
let mut storage = nvs.data::("sensitive")?;
storage.put("api_key", "secret123")?;
```
--------------------------------
### Initialize and Use WifiDriver
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/wifi.md
Demonstrates how to create, start, scan, and connect to Wi-Fi networks using the WifiDriver. Requires system loop and NVS partition for driver initialization.
```rust
use esp_idf_svc::wifi::{WifiDriver, WifiDeviceId};
use esp_idf_svc::eventloop::EspSystemEventLoop;
use esp_idf_svc::nvs::EspDefaultNvsPartition;
// Create driver with NVS support
let wifi_driver = WifiDriver::new(
modem,
sysloop,
Some(nvs_partition)
)?;
// Start the driver
let mut driver = wifi_driver;
driver.start()?;
// Scan for networks
use esp_idf_svc::wifi::config::ScanConfig;
driver.start_scan(&ScanConfig::default(), true)?;
let (results, count) = driver.get_scan_result_n::<20>()?;
// Connect to a network
use embedded_svc::wifi::ClientConfiguration;
let client_config = ClientConfiguration { /* ... */ };
driver.set_configuration(&embedded_svc::wifi::Configuration::Client(client_config))?;
driver.connect()?;
```
--------------------------------
### Encrypted Partition Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md
Shows how to set up and use an encrypted NVS partition, including the option to provide a key for encryption and decryption of sensitive data.
```APIDOC
## Encrypted Partition Usage
### Description
Illustrates how to set up and utilize an encrypted NVS partition. This includes the option to provide a key for encrypting and decrypting sensitive data.
### Usage
1. Initialize an encrypted NVS partition using `EspNvsPartition::::take_with_key("nvs_encrypted", Some("nvs_keys"))?`.
2. Obtain a namespace handle using `nvs.data::("sensitive")?`.
3. Store sensitive data using `storage.put(key, value)?`.
```
--------------------------------
### EspHttpClient Method (get)
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-client.md
Initiates a GET request to a specified URL. Returns a connection object for further manipulation or an error.
```rust
pub fn get(&mut self, url: &str) -> Result
```
--------------------------------
### Default Partition Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md
Demonstrates how to initialize and use the default NVS partition for storing and retrieving data, including creating namespace handles and managing key-value pairs.
```APIDOC
## Default Partition Usage
### Description
Initializes and utilizes the default NVS partition for storing and retrieving data. This includes creating namespace handles and managing key-value pairs.
### Usage
1. Initialize the default NVS partition using `EspDefaultNvsPartition::take_default()?`.
2. Obtain a namespace handle using `nvs.data::("myapp")?`.
3. Store data using `storage.put(key, value)?`.
4. Retrieve data using `storage.get(key)?.unwrap_or(default_value)`.
5. Check for key existence using `storage.contains(key)?`.
6. Remove a key-value pair using `storage.remove(key)?`.
```
--------------------------------
### Custom Partition Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md
Illustrates how to use a custom NVS partition by specifying its name during initialization, enabling storage and retrieval of data within that specific partition.
```APIDOC
## Custom Partition Usage
### Description
Demonstrates the usage of a custom NVS partition by specifying its name during initialization. This allows for data storage and retrieval within a designated partition.
### Usage
1. Initialize a custom NVS partition using `EspNvsPartition::::take("custom_partition")?`.
2. Obtain a namespace handle using `nvs.data::("settings")?`.
3. Store data using `storage.put(key, value)?`.
```
--------------------------------
### Partition Instance Methods
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md
Methods to get information about a specific partition instance.
```APIDOC
## Partition Instance Methods
### get_label()
#### Description
Gets the human-readable label/name of the partition.
#### Signature
```rust
pub fn get_label(&self) -> Result
```
#### Returns
`Result` - Partition name or error.
#### Example
```rust
let partition = Partition::find(...)?;
println!("Partition: {}", partition.get_label()?);
```
### get_offset()
#### Description
Gets the flash memory offset where this partition starts.
#### Signature
```rust
pub fn get_offset(&self) -> Result
```
#### Returns
`Result` - Offset in bytes or error.
### get_size()
#### Description
Gets the size of this partition in bytes.
#### Signature
```rust
pub fn get_size(&self) -> Result
```
#### Returns
`Result` - Size in bytes or error.
### get_kind()
#### Description
Gets the partition type.
#### Signature
```rust
pub fn get_kind(&self) -> Result
```
#### Returns
`Result` - Partition type or error.
### get_subtype()
#### Description
Gets the partition subtype as raw value.
#### Signature
```rust
pub fn get_subtype(&self) -> Result
```
#### Returns
`Result` - Subtype code or error.
### read_raw()
#### Description
Reads raw bytes from the partition.
#### Signature
```rust
pub fn read_raw(&self, offset: u32, buf: &mut [u8]) -> Result
```
#### Parameters
- **offset** (`u32`) - Required - Offset within partition
- **buf** (`&mut [u8]`) - Required - Buffer to read into
#### Returns
`Result` - Bytes read or error.
### write_raw()
#### Description
Writes raw bytes to the partition (typically for OTA or user data).
#### Signature
```rust
pub fn write_raw(&mut self, offset: u32, data: &[u8]) -> Result
```
#### Parameters
- **offset** (`u32`) - Required - Offset within partition
- **data** (`&[u8]`) - Required - Data to write
#### Returns
`Result` - Bytes written or error.
```
--------------------------------
### EthDriver::start
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ethernet.md
Starts the Ethernet interface, enabling network connectivity.
```APIDOC
## EthDriver::start
### Description
Starts the Ethernet interface, enabling network connectivity.
### Method
`pub fn start(&mut self) -> Result<(), EspError>`
### Parameters
This method takes no parameters.
### Response
#### Success Response
- `Result<(), EspError>`: Returns Ok(()) on success, or an EspError if the interface fails to start.
```
--------------------------------
### Simple GET Request
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-client.md
Performs a basic GET request to a specified URL and prints the response status and body. Requires the `EspHttpClient` to be initialized with default settings.
```rust
use esp_idf_svc::http::client::EspHttpClient;
let mut client = EspHttpClient::new_default()?;
let mut response = client.get("http://api.example.com/data")?.submit()?;
let mut buffer = [0u8; 1024];
let bytes_read = response.read(&mut buffer)?;
let response_text = std::str::from_utf8(&buffer[..bytes_read])?;
println!("Status: {}", response.status_code());
println!("Response: {}", response_text);
```
--------------------------------
### Synchronous Periodic Timer Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md
Shows how to set up and use a synchronous periodic timer. The timer is configured to fire repeatedly, and its execution count is checked after cancellation.
```rust
use esp_idf_svc::timer::EspTimerService;
use std::time::Duration;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
let timer_service = EspTimerService::new()?;
let count = Arc::new(AtomicU32::new(0));
let count_clone = count.clone();
let timer = timer_service.create(move || {
count_clone.fetch_add(1, Ordering::AcqRel);
})?;
timer.every(Duration::from_millis(10))?;
std::thread::sleep(Duration::from_millis(100));
timer.cancel()?;
let final_count = count.load(Ordering::Acquire);
assert!(final_count >= 9); // ~10 ticks in 100ms
```
--------------------------------
### Rust API Reference Structure Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/INDEX.md
Illustrates the standard format for documenting Rust modules, including overview, types, methods, parameters, return values, and source file location. This structure ensures consistency and clarity in API documentation.
```rust
# Module Name
## Overview
[Description of module purpose]
## Main Types
### TypeName
[Type definition in code block]
#### Constructors/Methods
**method_name()**
```rust
signature
```
| Parameter | Type | Required | Default | Description |
[parameter table]
Returns `type` — description.
**Example:**
```rust
usage code
```
## Notes
[Important information]
## Source File
`src/module.rs`
```
--------------------------------
### OTA Partition Table Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md
Defines the required partition table structure for OTA updates, specifying partitions for OTA data and application images.
```plaintext
# Name Type SubType Offset Size
otadata data ota 0xd000 8K
app0 app ota_0 0x10000 1600K
app1 app ota_1 0x190000 1600K
```
--------------------------------
### EspTimer::every Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md
Schedules a periodic timer that calls a callback repeatedly at specified intervals. Use this for recurring tasks.
```rust
// Call closure every 100 milliseconds
timer.every(Duration::from_millis(100))?;
```
--------------------------------
### Discover HTTP Services (Python)
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md
This Python snippet uses the `zeroconf` library to discover HTTP services on the network. Ensure `zeroconf` is installed.
```python
from zeroconf import ServiceBrowser, Zeroconf
def on_service_found(zeroconf, service_type, name, state_change):
print(f"Service found: {name}")
zeroconf = Zeroconf()
ServiceBrowser(zeroconf, "_http._tcp.local.", on_service_found)
```
--------------------------------
### Synchronous One-Shot Timer Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md
Demonstrates creating and using a synchronous one-shot timer. The timer fires after a specified duration, and its execution is verified.
```rust
use esp_idf_svc::timer::EspTimerService;
use std::time::Duration;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
let timer_service = EspTimerService::new()?;
let fired = Arc::new(AtomicBool::new(false));
let fired_clone = fired.clone();
let timer = timer_service.create(move || {
fired_clone.store(true, Ordering::Release);
})?;
timer.after(Duration::from_millis(500))?;
std::thread::sleep(Duration::from_secs(1));
assert!(fired.load(Ordering::Acquire));
```
--------------------------------
### Example: Storing and Retrieving Different Data Types
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md
Illustrates how to store various data types (integer, float, string, byte array) in an NVS partition and then retrieve them, handling potential missing values.
```rust
use esp_idf_svc::nvs::EspDefaultNvsPartition;
let nvs = EspDefaultNvsPartition::take_default()?;
let mut storage = nvs.data("app")?;
// Store different types
storage.put("boot_count", 1u32)?;
storage.put("temperature", 23.5f32)?;
storage.put("device_id", "ESP32-001")?;
storage.put("mac_addr", &[0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E])?;
// Retrieve them
let count: u32 = storage.get("boot_count")?.unwrap_or(0);
let temp: f32 = storage.get("temperature")?.unwrap_or(0.0);
let id: String = storage.get("device_id")?.unwrap_or_default();
```
--------------------------------
### EspTimerService::create Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md
Creates a timer using the EspTimerService, which provides automatic lifecycle management. This is useful for creating timers within a managed service context, ensuring proper cleanup. The callback is executed on each timer event.
```rust
use esp_idf_svc::timer::EspTimerService;
use std::time::Duration;
let timer_service = EspTimerService::new()?;
let counter = std::sync::Arc::new(std::sync::atomic::AtomicU32::new(0));
let counter_clone = counter.clone();
let timer = timer_service.create(move || {
counter_clone.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
})?;
// Fire callback every 50ms
timer.every(Duration::from_millis(50))?;
// Let it run for a bit
std::thread::sleep(Duration::from_secs(1));
// Stop
timer.cancel()?;
println!("Count: {}", counter.load(std::sync::atomic::Ordering::Relaxed));
```
--------------------------------
### EspHttpServer Methods and Configuration
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/DELIVERABLES.txt
Enables the creation and management of an HTTP server. Supports handler registration for various request types (function and WebSocket), detailed configuration, and HTTPS setup.
```APIDOC
## EspHttpServer
### Description
Enables the creation and management of an HTTP server. Supports handler registration for various request types (function and WebSocket), detailed configuration, and HTTPS setup.
### Constructors
- `EspHttpServer::new()`
### Methods
- `fn_handler(path, handler)`: Register a function-based handler.
- `ws_handler(path, handler)`: Register a WebSocket handler.
### Configuration
- `Configuration` struct with 16 fields.
- `KeepAlive` configuration.
### Types
- `Request` struct
- `Response` struct
- `Method` enum (9 HTTP verbs)
### Examples
4 usage examples are provided, including GET, POST, API, and WebSocket handling.
```
--------------------------------
### Initiate WiFi Network Scan
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/wifi.md
Starts a WiFi network scan. Provide a `ScanConfig` for scan parameters and a boolean to indicate if the operation should block until completion.
```rust
fn start_scan(
&mut self,
scan_config: &config::ScanConfig,
blocking: bool,
) -> Result<(), EspError>
```
--------------------------------
### Example ESP-IDF SDK Configuration
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/configuration.md
Common ESP-IDF settings that can be configured in `sdkconfig.defaults` or via `menuconfig`. These include HTTP server limits, WiFi buffer sizes, NVS encryption, Bluetooth enablement, task name lengths, and SPIRAM configuration.
```ini
# HTTP Server
CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024
# WiFi
CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
# NVS
CONFIG_NVS_ENCRYPTION_ENABLED=y
# Bluetooth
CONFIG_BT_ENABLED=y
CONFIG_BLUEDROID_ENABLED=y
# Threading
CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
# Memory
CONFIG_SPIRAM=y
CONFIG_SPIRAM_MODE_QUAD=y
```
--------------------------------
### MQTT Broker Discovery with mDNS
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md
Example of advertising an MQTT broker using mDNS. This includes setting a hostname and creating services for both standard MQTT (port 1883) and MQTT over TLS (port 8883), along with their respective properties. Clients can discover these services using the specified service and protocol.
```rust
use esp_idf_svc::mdns::EspMdns;
let mut mdns = EspMdns::new()?;
mdns.set_hostname("iot-hub")?;
// Advertise MQTT broker
let mut mqtt_service = mdns.create_service("mqtt", "tcp", 1883)?;
mqtt_service.set_properties(&[
("version", "3.1.1"),
("auth", "optional"),
("tls", "false"),
])?;
// Advertise MQTT over TLS
let mut mqtt_tls = mdns.create_service("mqtt", "tcp", 8883)?;
mqtt_tls.set_property("tls", "true")?;
// Clients can discover with: _mqtt._tcp.local
```
--------------------------------
### Initialize WiFi and Connect
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/README.md
Demonstrates how to initialize the WiFi driver, set client configuration with SSID, authentication method, and password, and then connect to a WiFi network.
```rust
use esp_idf_svc::wifi::{WifiDriver, WifiDeviceId, ClientConfiguration, AuthMethod};
use embedded_svc::wifi::Configuration;
let wifi = WifiDriver::new(modem, sysloop, nvs)?;
let mut driver = wifi;
driver.start()?;
let client_config = ClientConfiguration {
ssid: "MyNetwork".try_into()?,
auth_method: AuthMethod::WPA2Personal,
password: "Password123".try_into()?,
..Default::default()
};
driver.set_configuration(&Configuration::Client(client_config))?;
driver.connect()?;
```
--------------------------------
### Get OTA Partition Offset
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md
Returns the starting flash memory offset for a given OTA partition. Useful for low-level memory operations.
```rust
pub fn get_offset(&self) -> Result
```
--------------------------------
### RawStorage Methods for NVS
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md
Provides low-level key-value access methods for NVS partitions, including getting, setting, removing, and checking for the existence of raw data.
```rust
pub fn get_raw(&self, name_space: &str, key: &str) -> Result, Self::Error>;
pub fn set_raw(&mut self, name_space: &str, key: &str, data: &[u8]) -> Result<(), Self::Error>;
pub fn remove(&mut self, name_space: &str, key: &str) -> Result<(), Self::Error>;
pub fn contains(&self, name_space: &str, key: &str) -> Result;
```
--------------------------------
### Validate Current OTA Partition and Rollback
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md
Checks the validity of the currently running firmware partition and provides an example of how to initiate a rollback to a previous partition if the current one is corrupt. Uses `EspOtaPartition`.
```rust
use esp_idf_svc::ota::EspOtaPartition;
// Get currently running partition
let running = EspOtaPartition::get_running_partition()?;
println!("Running partition: {:?}", running.get_label()?);
// Check if it's valid
if running.is_valid()? {
println!("Current firmware is valid");
} else {
println!("Current firmware is corrupt!");
// Could rollback to previous partition here
if let Ok(Some(update_part)) = EspOtaPartition::get_update_partition() {
EspOtaPartition::set_boot_partition(&update_part)?;
esp_idf_svc::hal::reset::restart();
}
}
```
--------------------------------
### Iterate and Read ESP-IDF Partition Labels and Sizes
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md
Use `Partition::iterate` to get a list of all partitions of a given type and then use instance methods like `get_label` and `get_size` to retrieve their details. This is helpful for discovering and inspecting available partitions.
```rust
use esp_idf_svc::partition::{Partition, PartitionType};
let partitions = Partition::iterate(PartitionType::Data, None)?;
for partition in partitions {
println!("Name: {}", partition.get_label()?);
println!("Size: {} bytes", partition.get_size()?);
}
```
--------------------------------
### Dynamic mDNS Property Updates
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md
Demonstrates dynamic updates of mDNS service properties. This example shows how to initially set properties like 'type' and 'location', and then later update them with 'status' and 'readings', or remove properties using `remove_property`.
```rust
use esp_idf_svc::mdns::EspMdns;
let mut mdns = EspMdns::new()?;
mdns.set_hostname("sensor")?;
let mut service = mdns.create_service("http", "tcp", 8080)?;
service.set_property("type", "temperature_sensor")?;
service.set_property("location", "living_room")?;
// Later, update properties
service.set_property("status", "online")?;
service.set_property("readings", "42")?;
// Or remove old properties
service.remove_property("status")?;
```
--------------------------------
### List All Partitions
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md
Iterates through and prints details for all application and data partitions on the device. Requires `esp_idf_svc::partition`.
```rust
use esp_idf_svc::partition::{Partition, PartitionType};
fn list_partitions() -> Result<(), EspError> {
println!("=== Application Partitions ===");
let apps = Partition::iterate(PartitionType::App, None)?;
for partition in apps {
let label = partition.get_label()?;
let size = partition.get_size()?;
let offset = partition.get_offset()?;
println!(" {} @ 0x{:x} ({} bytes)", label, offset, size);
}
println!("\n=== Data Partitions ===");
let data = Partition::iterate(PartitionType::Data, None)?;
for partition in data {
let label = partition.get_label()?;
let size = partition.get_size()?;
let offset = partition.get_offset()?;
println!(" {} @ 0x{:x} ({} bytes)", label, offset, size);
}
Ok(())
}
```
--------------------------------
### EthDriver Get Capabilities Method
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ethernet.md
Retrieves the driver's capabilities. Returns a Result containing the capabilities or an error.
```rust
pub fn get_capabilities(&self) -> Result
```
--------------------------------
### List Available OTA Partitions
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md
Iterates through all available OTA partitions of type 'App' and prints their labels, sizes, and indicates which one is currently running. Requires `Partition` and `PartitionType`.
```rust
use esp_idf_svc::partition::{Partition, PartitionType};
let running = EspOtaPartition::get_running_partition()?;
let running_label = running.get_label()?;
println!("OTA Partitions:");
for partition in Partition::iterate(PartitionType::App, None)? {
let label = partition.get_label()?;
let is_running = label == running_label;
let size = partition.get_size()?;
println!(
" {} - {} bytes{}",
label,
size,
if is_running { " [RUNNING]" } else { "" }
);
}
```
--------------------------------
### Get OTA Partition Label
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md
Retrieves the string label (name) of an OTA partition. This is often used for identification purposes.
```rust
pub fn get_label(&self) -> Result
```
--------------------------------
### Check OTA Partition Validity
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md
Verifies if the partition currently being written to is valid for an OTA update. Call this before starting to write data.
```rust
pub fn is_valid(&self) -> Result
```
--------------------------------
### new()
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mqtt.md
Creates a new MQTT client instance. It requires the broker URL, client configuration, and a handler function for MQTT events.
```APIDOC
## new()
### Description
Creates a new MQTT client.
### Signature
```rust
pub fn new FnMut(Event<'a>) -> Result<()> + Send + 'static>(
url: &str,
client_config: &MqttClientConfiguration,
handler: F,
) -> Result<(Self, Connection), EspError>
```
### Parameters
#### Path Parameters
- **url** (`&str`) - Required - Broker URL (mqtt://, mqtts://, ws://, wss://)
- **client_config** (`&MqttClientConfiguration`) - Required - Client configuration
- **handler** (`F`) - Required - Closure handling MQTT events
### Returns
- `Result<(EspMqttClient, Connection), EspError>` - Client and connection handle or error.
```
--------------------------------
### Async One-Shot Timer Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md
Demonstrates the usage of EspAsyncTimer for an asynchronous one-shot delay. The function waits for a specified duration before proceeding.
```rust
use esp_idf_svc::timer::EspAsyncTimer;
use std::time::Duration;
async fn wait_example() -> Result<(), EspError> {
let mut timer = EspAsyncTimer::new()?;
println!("Waiting...");
timer.after(Duration::from_secs(1)).await?;
println!("Done!");
Ok(())
}
```
--------------------------------
### String Definition
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/types.md
UTF-8 encoded string requiring `alloc`. Supports methods for creation, appending, getting string slices, and length.
```rust
pub struct String { /* ... */ }
```
--------------------------------
### Connect to MQTT Broker
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/README.md
Illustrates connecting to an MQTT broker, setting a client ID, subscribing to a topic, and publishing a message.
```rust
use esp_idf_svc::mqtt::client::{EspMqttClient, MqttClientConfiguration, QoS};
let config = MqttClientConfiguration {
client_id: Some("esp32"),
..Default::default()
};
let (mut client, _conn) = EspMqttClient::new(
"mqtt://broker.example.com",
&config,
|_msg| Ok(()),
)?;
client.subscribe("home/temp", QoS::AtMostOnce)?;
client.publish("home/status", QoS::AtMostOnce, false, b"online")?;
```
--------------------------------
### Async Periodic Timer Example
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md
Illustrates how to use EspAsyncTimer for periodic asynchronous operations. The timer triggers repeatedly, and the number of ticks is printed.
```rust
use esp_idf_svc::timer::EspAsyncTimer;
use std::time::Duration;
async fn periodic_example() -> Result<(), EspError> {
let mut timer = EspAsyncTimer::new()?;
timer.every(Duration::from_millis(100))?;
for i in 0..10 {
timer.tick().await?;
println!("Tick {}", i);
}
Ok(())
}
```
--------------------------------
### EspMdns::new
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md
Creates and initializes the mDNS responder. This is the entry point for using the mDNS service.
```APIDOC
## EspMdns::new
### Description
Creates and initializes the mDNS responder.
### Method
Rust function call
### Parameters
None
### Response
#### Success Response
- **EspMdns** (EspMdns) - An initialized mDNS instance.
- **EspError** (EspError) - An error if initialization fails.
### Example
```rust
let mdns = EspMdns::new()?;
```
```
--------------------------------
### Get ESP-IDF Partition Label
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md
Retrieve the human-readable name of a partition using its `get_label` method. This is often used after finding a partition to identify it.
```rust
let partition = Partition::find(...)?;
println!("Partition: {}", partition.get_label()?);
```
--------------------------------
### List All Services (Linux/macOS)
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md
Use `avahi-browse -a` to list all discoverable mDNS services on the network.
```bash
avahi-browse -a
```
--------------------------------
### Perform Basic OTA Update from HTTP
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md
Initiates an OTA update by downloading firmware from a given URL via HTTP and writing it to the OTA partition. Requires `OtaUpdate` and `EspHttpClient`.
```rust
use esp_idf_svc::ota::OtaUpdate;
use esp_idf_svc::http::client::*;
fn perform_ota_update(url: &str) -> Result<(), EspError> {
// Start OTA session
let mut ota = OtaUpdate::new()?;
// Download firmware via HTTP
let mut client = EspHttpClient::new_default()?;
let mut response = client.get(url)?.submit()?;
// Write downloaded data to OTA partition
let mut buffer = [0u8; 4096];
loop {
let len = response.read(&mut buffer)?;
if len == 0 {
break;
}
ota.write(&buffer[..len])?;
}
// Finalize and reboot
ota.complete()?;
esp_idf_svc::hal::reset::restart();
Ok(())
}
```
--------------------------------
### Get Currently Running OTA Partition
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md
Retrieves information about the OTA partition that is currently executing firmware. This is useful for debugging or status checks.
```rust
pub fn get_running_partition() -> Result
```
--------------------------------
### Create MQTT Client
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mqtt.md
Constructs a new MQTT client instance. Requires a broker URL, client configuration, and an event handler closure. The handler will be called for all MQTT events.
```rust
pub fn new FnMut(Event<'a>) -> Result<()> + Send + 'static>(
url: &str,
client_config: &MqttClientConfiguration,
handler: F,
) -> Result<(Self, Connection), EspError>
```
--------------------------------
### Use Hardware Timer
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/README.md
Shows how to create and configure a hardware timer that triggers a closure at a specified interval, in this case, every second.
```rust
use esp_idf_svc::timer::EspTimerService;
use std::time::Duration;
let timer_service = EspTimerService::new()?;
let timer = timer_service.create(|| println!("Tick!"))?;
timer.every(Duration::from_secs(1))?;
```
--------------------------------
### EspHttpClient Constructor (new)
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-client.md
Creates a new HTTP client instance with custom configuration. Requires a Configuration struct as input.
```rust
pub fn new(config: &Configuration) -> Result
```
--------------------------------
### EspHttpClient Constructor (new_default)
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-client.md
Creates a new HTTP client instance using default configuration settings. This is a convenient way to initialize the client without specifying individual configuration parameters.
```rust
pub fn new_default() -> Result
```
--------------------------------
### EspHttpRequest Method (status_code)
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-client.md
Gets the HTTP response status code. This is a simple integer representing the status (e.g., 200 for OK, 404 for Not Found).
```rust
pub fn status_code(&self) -> u16
```
--------------------------------
### RawStorage Methods
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md
Provides low-level key-value access operations for NVS partitions, including getting, setting, removing, and checking for the existence of raw data.
```APIDOC
## RawStorage Methods
### Description
Provides low-level key-value access operations for NVS partitions, including getting, setting, removing, and checking for the existence of raw data.
### Methods
- `get_raw(name_space: &str, key: &str) -> Result, Self::Error>`: Retrieves raw data associated with a key in a given namespace.
- `set_raw(name_space: &str, key: &str, data: &[u8]) -> Result<(), Self::Error>`: Sets raw data for a given key in a namespace.
- `remove(name_space: &str, key: &str) -> Result<(), Self::Error>`: Removes a key-value pair from the NVS.
- `contains(name_space: &str, key: &str) -> Result`: Checks if a key exists within a given namespace.
```
--------------------------------
### WifiDriver::new (with NVS)
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/wifi.md
Initializes the WiFi driver with an optional NVS partition for persistent configuration.
```APIDOC
## WifiDriver::new (with NVS)
### Description
Initializes the WiFi driver with an optional NVS partition for persistent configuration.
### Method
`new`
### Parameters
#### Path Parameters
- **_modem** (`M: WifiModemPeripheral`) - Required - WiFi modem peripheral
- **sysloop** (`EspSystemEventLoop`) - Required - System event loop for WiFi events
- **nvs** (`Option`) - Optional - Optional NVS partition for persistent config
### Returns
`Result` - Initialized WiFi driver or error.
```
--------------------------------
### Get ESP-IDF Partition Subtype
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md
Fetch the raw subtype code for a partition using `get_subtype`. This provides a more granular classification than the partition type alone.
```rust
pub fn get_subtype(&self) -> Result
```
--------------------------------
### Get OTA Partition Size
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md
Returns the total size in bytes of an OTA partition. Essential for calculating buffer sizes or verifying data integrity.
```rust
pub fn get_size(&self) -> Result
```
--------------------------------
### Get Next Update OTA Partition
Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md
Identifies the OTA partition designated for the next firmware update. Returns `None` if no update partition is configured.
```rust
pub fn get_update_partition() -> Result