An open-source Flutter client for controlling ESP32-based Smart Locks and Smart Lamps over your local WiFi network. Manage multiple IoT devices from one beautiful, Material 3 mobile app.
- Smart Lock Control — Lock/unlock doors remotely with a single swipe gesture and auto-lock countdown
- Smart Lamp Control — Turn smart lamps on/off with one tap
- Multi-Device Management — Add, edit, delete, and switch between multiple devices
- Provisioning Wizard — Guided multi-step setup for connecting new devices
- Secure Storage — Tokens and credentials stored with platform-native encryption (Android EncryptedSharedPreferences, iOS Keychain)
- Device Simulators — Node.js/Express mock servers for testing without real hardware
- Dark Theme — Modern dark UI built with Material 3 components
- Connection Status — Real-time indicators (Active, Connecting, Offline, Error)
darmi-mobile/
├── lib/
│ ├── api/lock_api.dart # HTTP client for device REST API
│ ├── screens/ # UI screens
│ │ ├── splash_screen.dart # App entry with animated logo
│ │ ├── onboarding_screen.dart # First-launch welcome
│ │ ├── setup_wizard.dart # Multi-step device provisioning
│ │ ├── home_shell.dart # Bottom nav + device switcher
│ │ ├── control_screen.dart # Main lock/lamp control UI
│ │ ├── devices_screen.dart # Device list management
│ │ ├── device_edit_screen.dart# Edit device settings
│ │ └── settings_screen.dart # App-level settings
│ ├── widgets/ # Reusable UI components
│ ├── settings/settings_store.dart # Secure persistent storage
│ ├── theme/ # Colors, spacing, Material 3 theme
│ └── main.dart # App entry point
├── simulator/ # Lock simulator (Node.js)
├── simulator-lamp/ # Lamp simulator (Node.js)
├── assets/ # Icons and logos
└── docs/ # UX/UI documentation
| Tool | Version | Purpose |
|---|---|---|
| Flutter SDK | >= 3.8.0 | Build and run the mobile app |
| Dart SDK | Included with Flutter | Language runtime |
| Node.js | >= 18.x | Run device simulators (for development/testing) |
| Android Studio or VS Code | Latest | IDE with Flutter plugin |
| Android SDK | API 21+ (Android 5.0+) | Android builds |
| Xcode | 14+ (macOS only) | iOS builds |
- Android: Enable developer options and USB debugging on a physical device, or use an Android emulator
- iOS: Apple Developer account for physical device testing; macOS with Xcode installed for simulator builds
git clone https://github.com/<your-org>/darmi-mobile.git
cd darmi-mobileflutter pub get# On connected Android device or emulator
flutter run
# On iOS simulator (macOS only)
flutter run -d ios
# On Linux desktop
flutter run -d linuxIf you don't have physical ESP32 hardware, use the built-in device simulators to test the app.
cd simulator
npm install
npm startThe lock simulator runs on http://127.0.0.1:1212 by default.
cd simulator-lamp
npm install
npm startThe lamp simulator runs on http://127.0.0.1:1213 by default.
- Start the simulator (see above)
- Open the Microlock app
- In the Setup Wizard, enter:
- Device Name: any name (e.g. "Test Lock")
- IP Address:
127.0.0.1(or your machine's local IP) - Port:
1212(lock) or1213(lamp) - Token:
demo-token(default)
- Tap Test Connection — you should see a green "Connected" status
- Save the device
| Variable | Default | Description |
|---|---|---|
PORT |
1212 |
HTTP server port |
MICROLOCK_TOKEN |
demo-token |
Authentication token |
MICROLOCK_NAME |
auto-generated | Device name shown in API |
MICROLOCK_AP_IP |
machine's LAN IP | IP address in AP mode |
MICROLOCK_STA_IP |
192.168.1.77 |
IP address in STA mode |
Example with custom configuration:
PORT=1212 MICROLOCK_TOKEN=my-secret-token MICROLOCK_NAME="Front Door" npm startThe app communicates with devices over HTTP REST. Below are the endpoints implemented by both the ESP32 firmware and the simulators.
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/ |
No | Health check / ping |
POST |
/lock |
Yes | Lock the door |
POST |
/unlock |
Yes | Unlock the door |
POST |
/status |
Yes | Get current lock state |
GET |
/config |
No | Get provisioning config |
POST |
/config |
No | Update provisioning config |
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/ |
No | Health check / ping |
POST |
/on |
Yes | Turn lamp on |
POST |
/off |
Yes | Turn lamp off |
POST |
/toggle |
Yes | Toggle lamp state |
POST |
/status |
Yes | Get current lamp state |
POST |
/config |
Yes | Update AP config |
All state-changing requests require a JSON body with a token field:
{ "token": "your-device-token" }Responses return the new state:
{ "state": "locked" }| Package | Purpose |
|---|---|
flutter |
UI framework |
http |
HTTP client for device API |
flutter_secure_storage |
Encrypted credential storage |
cupertino_icons |
iOS-style icons |
flutter_lints |
Code quality rules |
- One primary action per screen — only one button that changes state (never both Lock and Unlock at once)
- Auto-lock — locks automatically after 5 seconds for safety
- Device switching without navigation — switch active device from the Home tab via a bottom sheet selector
- IP hidden from UI — users only see device names; technical details are abstracted away
- Slide-to-unlock — prevents accidental door unlocking via swipe gesture
We welcome contributions! Please see our templates:
- Bug reports: Use the Bug Report template
- Feature requests: Use the Feature Request template
- Pull requests: Use the PR Template
# 1. Fork and clone
git clone https://github.com/<your-username>/darmi-mobile.git
cd darmi-mobile
# 2. Create a feature branch
git checkout -b feature/my-feature
# 3. Make changes and verify
flutter analyze
flutter test
# 4. Commit and push
git add .
git commit -m "feat: add my feature"
git push origin feature/my-feature
# 5. Open a Pull RequestThis project is open source. Please check the repository for license details.
- UI/UX Flow — Full screen-by-screen wireframes and navigation structure
- UX Specification — Design principles and component recommendations