Skip to content

OMARINO-DE/meterreaderapp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

MeterReaderApp πŸ“±βš‘# meter_reader_app

Β© OMARINO IT ServicesA new Flutter project.

A mobile application built with Flutter that captures electricity meter readings using OCR technology and synchronizes data directly to Microsoft Excel Online via the Microsoft Graph API.## Getting Started

---This project is a starting point for a Flutter application.

πŸ—οΈ System ArchitectureA few resources to get you started if this is your first Flutter project:

  • Framework: Flutter (Dart)- Cookbook: Useful Flutter samples

  • OCR Engine: Google ML Kit Text Recognition

  • Authentication: Azure AD OAuth 2.0 (via aad_oauth)For help getting started with Flutter development, view the

  • Cloud Storage: Microsoft OneDrive + Excel Onlineonline documentation, which offers tutorials,

  • API: Microsoft Graph APIsamples, guidance on mobile development, and a full API reference.

  • Local Storage: SQLite (offline mode)

  • State Management: Provider pattern

Architectural Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Camera    │─────▢│  OCR Engine  │─────▢│   Preview   β”‚
β”‚   Capture   β”‚      β”‚  (ML Kit)    β”‚      β”‚   Screen    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                   β”‚
                                                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Excel     │◀─────│ Graph API    │◀─────│ Auth Serviceβ”‚
β”‚   Online    β”‚      β”‚  Service     β”‚      β”‚  (Azure AD) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
                            β–Ό
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚ Local SQLite β”‚
                     β”‚ (Offline)    β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Project Structure

meter_reader_app/
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ main.dart                    # App entry point
β”‚   β”œβ”€β”€ models/                      # Data models
β”‚   β”‚   β”œβ”€β”€ meter_reading.dart       # MeterReading model
β”‚   β”‚   └── upload_status.dart       # Upload status tracking
β”‚   β”œβ”€β”€ screens/                     # UI screens
β”‚   β”‚   β”œβ”€β”€ splash_screen.dart       # Splash with OMARINO branding
β”‚   β”‚   β”œβ”€β”€ home_screen.dart         # Main screen with scan button
β”‚   β”‚   β”œβ”€β”€ preview_screen.dart      # OCR results preview
β”‚   β”‚   └── history_screen.dart      # Past readings
β”‚   β”œβ”€β”€ services/                    # Business logic services
β”‚   β”‚   β”œβ”€β”€ auth_service.dart        # Azure AD authentication
β”‚   β”‚   β”œβ”€β”€ graph_service.dart       # Microsoft Graph API operations
β”‚   β”‚   β”œβ”€β”€ ocr_service.dart         # OCR processing
β”‚   β”‚   β”œβ”€β”€ camera_service.dart      # Camera capture
β”‚   β”‚   └── database_service.dart    # Local SQLite operations
β”‚   └── utils/                       # Helper utilities
β”‚       β”œβ”€β”€ constants.dart           # App constants
β”‚       β”œβ”€β”€ config.dart              # Azure config loader
β”‚       └── theme.dart               # Material Design 3 theme
β”œβ”€β”€ assets/
β”‚   └── images/                      # Logo and branding assets
β”œβ”€β”€ android/                         # Android configuration
β”œβ”€β”€ ios/                             # iOS configuration
β”œβ”€β”€ config/
β”‚   └── azure_config.json            # Azure app registration details
└── pubspec.yaml                     # Dependencies

πŸš€ Setup Instructions

Prerequisites

  • Flutter SDK (3.0+)
  • Android Studio / Xcode (for mobile development)
  • Microsoft Azure account
  • OneDrive account

Step 1: Clone and Install Dependencies

git clone <repository-url>
cd MeterReaderApp
flutter pub get

Step 2: Azure App Registration

  1. Go to Azure Portal: https://portal.azure.com

  2. Navigate to: Azure Active Directory β†’ App registrations β†’ New registration

  3. Configure Application:

    • Name: MeterReaderApp
    • Supported account types: Accounts in any organizational directory and personal Microsoft accounts
    • Redirect URI:
      • Platform: Public client/native (mobile & desktop)
      • URI: msauth://com.omarinoitservices.meter_reader_app/auth
  4. API Permissions (Microsoft Graph):

    • Files.ReadWrite (Delegated)
    • User.Read (Delegated)
    • offline_access (Delegated)

    Click "Grant admin consent" if required.

  5. Copy Configuration:

    • Application (client) ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    • Directory (tenant) ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Step 3: Configure the App

Create a file: config/azure_config.json

{
  "client_id": "YOUR_CLIENT_ID_HERE",
  "tenant_id": "YOUR_TENANT_ID_HERE",
  "redirect_uri": "msauth://com.omarinoitservices.meter_reader_app/auth",
  "scopes": [
    "User.Read",
    "Files.ReadWrite",
    "offline_access"
  ]
}

IMPORTANT: Add config/azure_config.json to .gitignore to keep credentials secure.

Step 4: Platform-Specific Configuration

Android (android/app/src/main/AndroidManifest.xml)

Add permissions inside <manifest>:

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Add inside <application> β†’ <activity>:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data
        android:scheme="msauth"
        android:host="com.omarinoitservices.meter_reader_app"
        android:path="/auth" />
</intent-filter>

iOS (ios/Runner/Info.plist)

Add before </dict>:

<key>NSCameraUsageDescription</key>
<string>This app needs camera access to capture meter readings</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs photo library access to select meter images</string>
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>msauth</string>
        </array>
    </dict>
</array>

πŸ”§ Development Workflow

Run the App

# Run on connected device
flutter run

# Run in debug mode
flutter run --debug

# Run in release mode (production)
flutter run --release

Build for Production

# Android APK
flutter build apk --release

# iOS Archive (requires Mac)
flutter build ios --release

🧩 Module Communication

Authentication Flow

  1. User clicks "Login" β†’ AuthService.login()
  2. Azure AD OAuth redirect β†’ User authenticates
  3. Access token stored securely β†’ Token auto-refresh enabled
  4. Token passed to GraphService for API calls

OCR Flow

  1. User captures image β†’ CameraService.captureImage()
  2. Image preprocessing β†’ OcrService.processImage()
  3. Text extraction β†’ Parse meter number & reading
  4. Return structured JSON: {meterNumber, reading, timestamp}

Excel Upload Flow

  1. User confirms data β†’ GraphService.uploadToExcel()
  2. Check if file exists: GET /me/drive/root:/MeterReader/data.xlsx
  3. If not exists: Create Excel file with headers
  4. Append row: POST /me/drive/root:/MeterReader/data.xlsx:/workbook/tables/Table1/rows/add

Offline Mode

  • Failed uploads saved to local SQLite database
  • Background sync job retries when network available
  • User notified of pending uploads in UI

πŸ“Š Data Model

MeterReading

{
  "id": "uuid",
  "meterNumber": "123456789",
  "reading": "54321",
  "timestamp": "2025-10-20T14:30:00Z",
  "imagePath": "/local/path/image.jpg",
  "uploadStatus": "pending|uploaded|failed",
  "uploadedAt": "2025-10-20T14:31:00Z"
}

🎨 Design System

  • Theme: Material Design 3
  • Colors: Custom OMARINO IT Services branding
  • Dark Mode: Fully supported
  • Typography: Roboto (default Material)

πŸ§ͺ Testing

Unit Tests

flutter test

Integration Tests

flutter drive --target=test_driver/app.dart

Manual Testing Checklist

  • Camera capture works on Android & iOS
  • OCR correctly extracts meter number and reading
  • Authentication flow completes successfully
  • Excel file is created in OneDrive if missing
  • Data appends correctly to Excel Online
  • Offline mode saves data locally
  • Background sync works when network restored
  • Dark mode renders correctly
  • App handles errors gracefully

πŸ” Security Considerations

  • Tokens: Stored securely using flutter_secure_storage
  • API Keys: Never hardcoded, loaded from config file
  • Permissions: Request only when needed
  • Data: Images deleted after successful upload (optional)

πŸ“ License

Β© 2025 OMARINO IT Services. All rights reserved.


🀝 Support

For issues or questions, contact: OMARINO IT Services


πŸ—ΊοΈ Roadmap

  • Project setup and architecture
  • Camera capture implementation
  • OCR integration
  • Azure AD authentication
  • Microsoft Graph API integration
  • Offline mode
  • UI/UX polish
  • Beta testing
  • Production release

Built with ❀️ by OMARINO IT Services

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published