esp_provisioning_wifi 0.1.1 copy "esp_provisioning_wifi: ^0.1.1" to clipboard
esp_provisioning_wifi: ^0.1.1 copied to clipboard

Bloc wrapper over 'flutter_esp_ble_prov' which provisions WiFi on Espressif ESP32 devices over Bluetooth using Espressif-provided provisioning libraries.

example/lib/main.dart

import 'package:esp_provisioning_wifi/esp_provisioning_wifi.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider(
        create: (_) => EspProvisioningBloc(),
        child: const MyAppView(),
      ),
    );
  }
}

class MyAppView extends StatefulWidget {
  const MyAppView({super.key});

  @override
  State<MyAppView> createState() => _MyAppViewState();
}

class _MyAppViewState extends State<MyAppView> {
  final double defaultPadding = 12.0;

  String feedbackMessage = '';

  final TextEditingController prefixController =
      TextEditingController(text: 'PROV_');
  final TextEditingController proofOfPossessionController =
      TextEditingController(text: 'abcd1234');
  final TextEditingController passphraseController = TextEditingController();

  void pushFeedback(String msg) {
    setState(() {
      feedbackMessage =
          feedbackMessage.isEmpty ? msg : '$feedbackMessage\n$msg';
    });
  }

  String _statusLabel(EspProvisioningStatus status) {
    switch (status) {
      case EspProvisioningStatus.initial:
        return 'initial';
      case EspProvisioningStatus.bleScanned:
        return 'bleScanned';
      case EspProvisioningStatus.deviceChosen:
        return 'deviceChosen';
      case EspProvisioningStatus.wifiScanned:
        return 'wifiScanned';
      case EspProvisioningStatus.networkChosen:
        return 'networkChosen';
      case EspProvisioningStatus.wifiProvisioned:
        return 'wifiProvisioned';
      case EspProvisioningStatus.error:
        return 'error';
    }
  }

  String _failureLabel(EspProvisioningFailure failure) {
    switch (failure) {
      case EspProvisioningFailure.none:
        return 'none';
      case EspProvisioningFailure.permissionDenied:
        return 'permissionDenied';
      case EspProvisioningFailure.timeout:
        return 'timeout';
      case EspProvisioningFailure.cancelled:
        return 'cancelled';
      case EspProvisioningFailure.deviceNotFound:
        return 'deviceNotFound';
      case EspProvisioningFailure.invalidResponse:
        return 'invalidResponse';
      case EspProvisioningFailure.platform:
        return 'platform';
      case EspProvisioningFailure.unknown:
        return 'unknown';
    }
  }

  void _onStateChanged(EspProvisioningState state) {
    switch (state.status) {
      case EspProvisioningStatus.bleScanned:
        pushFeedback(
          'BLE scan complete: ${state.bluetoothDevices.length} device(s)',
        );
        break;
      case EspProvisioningStatus.wifiScanned:
        pushFeedback(
          'Wi-Fi scan complete: ${state.wifiNetworks.length} network(s)',
        );
        break;
      case EspProvisioningStatus.wifiProvisioned:
        pushFeedback(
          state.wifiProvisioned
              ? 'Wi-Fi provisioned successfully'
              : 'Wi-Fi provisioning failed',
        );
        break;
      case EspProvisioningStatus.error:
        final details = state.errorMsg.isEmpty ? 'No details' : state.errorMsg;
        pushFeedback('Error (${_failureLabel(state.failure)}): $details');
        break;
      case EspProvisioningStatus.initial:
      case EspProvisioningStatus.deviceChosen:
      case EspProvisioningStatus.networkChosen:
        break;
    }
  }

  @override
  void dispose() {
    prefixController.dispose();
    proofOfPossessionController.dispose();
    passphraseController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return BlocConsumer<EspProvisioningBloc, EspProvisioningState>(
      listenWhen: (previous, current) =>
          previous.status != current.status ||
          previous.failure != current.failure ||
          previous.errorMsg != current.errorMsg,
      listener: (_, state) => _onStateChanged(state),
      builder: (context, state) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('ESP BLE Provisioning Example'),
            actions: [
              IconButton(
                icon: const Icon(Icons.bluetooth),
                onPressed: () {
                  context
                      .read<EspProvisioningBloc>()
                      .add(EspProvisioningEventStart(prefixController.text));
                  pushFeedback('Scanning BLE devices...');
                },
              ),
              IconButton(
                icon: const Icon(Icons.clear_all),
                onPressed: () {
                  setState(() {
                    feedbackMessage = '';
                  });
                },
              ),
            ],
          ),
          bottomSheet: SafeArea(
            child: Container(
              width: double.infinity,
              color: Colors.black87,
              padding: EdgeInsets.all(defaultPadding),
              child: Text(
                feedbackMessage,
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  color: Colors.green.shade600,
                ),
              ),
            ),
          ),
          body: SafeArea(
            child: Padding(
              padding: EdgeInsets.all(defaultPadding),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Card(
                    child: Padding(
                      padding: EdgeInsets.all(defaultPadding),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            'Status: ${_statusLabel(state.status)}',
                            style: const TextStyle(fontWeight: FontWeight.bold),
                          ),
                          const SizedBox(height: 6),
                          Text('Failure: ${_failureLabel(state.failure)}'),
                          if (state.errorMsg.isNotEmpty) ...[
                            const SizedBox(height: 6),
                            Text(
                              state.errorMsg,
                              style: const TextStyle(color: Colors.red),
                            ),
                          ],
                        ],
                      ),
                    ),
                  ),
                  Flexible(
                    child: Padding(
                      padding: EdgeInsets.all(defaultPadding),
                      child: Row(
                        children: [
                          const Flexible(
                            child: Text('Device Prefix'),
                          ),
                          Expanded(
                            child: TextField(
                              controller: prefixController,
                              decoration: const InputDecoration(
                                hintText: 'enter device prefix',
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                  Flexible(
                    child: Padding(
                      padding: EdgeInsets.all(defaultPadding),
                      child: const Text('BLE devices'),
                    ),
                  ),
                  Expanded(
                    child: ListView.builder(
                      itemCount: state.bluetoothDevices.length,
                      itemBuilder: (context, i) {
                        return ListTile(
                          title: Text(
                            state.bluetoothDevices[i],
                            style: TextStyle(
                              color: Colors.blue.shade700,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          onTap: () {
                            final bluetoothDevice = state.bluetoothDevices[i];
                            context.read<EspProvisioningBloc>().add(
                                  EspProvisioningEventBleSelected(
                                    bluetoothDevice,
                                    proofOfPossessionController.text,
                                  ),
                                );
                            pushFeedback(
                                'Scanning Wi-Fi on $bluetoothDevice...');
                          },
                        );
                      },
                    ),
                  ),
                  Flexible(
                    child: Padding(
                      padding: EdgeInsets.all(defaultPadding),
                      child: Row(
                        children: [
                          const Flexible(
                            child: Text('Proof of possession'),
                          ),
                          Expanded(
                            child: TextField(
                              controller: proofOfPossessionController,
                              decoration: const InputDecoration(
                                hintText: 'enter proof of possession string',
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                  Flexible(
                    child: Padding(
                      padding: EdgeInsets.all(defaultPadding),
                      child: const Text('WiFi networks'),
                    ),
                  ),
                  Expanded(
                    child: ListView.builder(
                      itemCount: state.wifiNetworks.length,
                      itemBuilder: (context, i) {
                        return ListTile(
                          title: Text(
                            state.wifiNetworks[i],
                            style: TextStyle(
                              color: Colors.green.shade700,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          onTap: () {
                            final wifiNetwork = state.wifiNetworks[i];
                            context.read<EspProvisioningBloc>().add(
                                  EspProvisioningEventWifiSelected(
                                    state.bluetoothDevice,
                                    proofOfPossessionController.text,
                                    wifiNetwork,
                                    passphraseController.text,
                                  ),
                                );
                            pushFeedback(
                              'Provisioning $wifiNetwork on ${state.bluetoothDevice}...',
                            );
                          },
                        );
                      },
                    ),
                  ),
                  Flexible(
                    child: Padding(
                      padding: EdgeInsets.all(defaultPadding),
                      child: Row(
                        children: [
                          const Flexible(
                            child: Text('WiFi Passphrase'),
                          ),
                          Expanded(
                            child: TextField(
                              controller: passphraseController,
                              decoration: const InputDecoration(
                                hintText: 'enter passphrase',
                              ),
                              obscureText: true,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}
4
likes
130
points
292
downloads

Documentation

API reference

Publisher

verified publishersleepasloth.com

Weekly Downloads

Bloc wrapper over 'flutter_esp_ble_prov' which provisions WiFi on Espressif ESP32 devices over Bluetooth using Espressif-provided provisioning libraries.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

bloc_concurrency, equatable, flutter, flutter_bloc, permission_handler, plugin_platform_interface

More

Packages that depend on esp_provisioning_wifi

Packages that implement esp_provisioning_wifi