Skip to content

Conversation

@Inuth0603
Copy link
Contributor

@Inuth0603 Inuth0603 commented Jan 5, 2026

Summary

Implemented support for the MLX90614 Infrared Temperature Sensor.

Changes

  • Added MLX90614 class for I2C communication.
  • Added MLX90614Provider for state management (includes error handling and safe loops).
  • Added MLX90614Screen to display Object and Ambient temperatures.
  • Registered provider in locator and main.
  • Added navigation in SensorsScreen.

Fixes

Closes #2992

Summary by Sourcery

Add MLX90614 infrared temperature sensor support, including UI, provider wiring, and platform plugin registration updates.

New Features:

  • Introduce MLX90614 sensor communication class over I2C to read ambient and object temperatures.
  • Add MLX90614Provider for managing MLX90614 sensor state and periodic data acquisition.
  • Add MLX90614Screen to display ambient and object temperature readings from the MLX90614 sensor.
  • Wire the MLX90614 sensor screen into the sensors navigation flow.

Bug Fixes:

  • Remove SHT21 imports and navigation cases that were causing build or runtime errors in the sensors screen.

Enhancements:

  • Register MLX90614Provider with the service locator and as a ChangeNotifierProvider in the app's main widget tree.
  • Update generated plugin registrants for Windows and macOS to include geolocation plugins where required.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 5, 2026

Reviewer's Guide

Adds end-to-end support for the MLX90614 infrared temperature sensor, including an I2C driver, a provider with a polling loop, a dedicated UI screen, and wiring into navigation, dependency injection, and platform plugin registration.

Sequence diagram for MLX90614Screen, provider, and sensor polling

sequenceDiagram
    actor User
    participant SensorsScreen
    participant MLX90614Screen
    participant MLX90614Provider
    participant getIt
    participant ScienceLab
    participant I2C
    participant MLX90614

    User->>SensorsScreen: tap sensor MLX90614
    SensorsScreen->>MLX90614Screen: Navigator.push
    activate MLX90614Screen

    MLX90614Screen->>MLX90614Screen: initState
    MLX90614Screen->>MLX90614Screen: addPostFrameCallback

    MLX90614Screen->>MLX90614Provider: Provider.of listen false
    MLX90614Screen->>getIt: getIt<ScienceLab>()
    getIt-->>MLX90614Screen: ScienceLab instance

    MLX90614Screen->>ScienceLab: isConnected()
    alt device connected
        MLX90614Screen->>I2C: I2C(scienceLab.mPacketHandler)
        MLX90614Screen->>MLX90614Provider: init(i2c)
        MLX90614Provider->>MLX90614: MLX90614(i2c)

        MLX90614Screen->>MLX90614Provider: startDataLog()
        activate MLX90614Provider
        loop while isWorking
            MLX90614Provider->>MLX90614: getAmbientTemperature()
            MLX90614->>I2C: readBulk(address, ambientTempReg, 2)
            I2C-->>MLX90614: List<int> data
            MLX90614-->>MLX90614Provider: double ambientTemp

            MLX90614Provider->>MLX90614: getObjectTemperature()
            MLX90614->>I2C: readBulk(address, objectTempReg, 2)
            I2C-->>MLX90614: List<int> data
            MLX90614-->>MLX90614Provider: double objectTemp

            MLX90614Provider->>MLX90614Provider: notifyListeners()
            MLX90614Provider-->>MLX90614Screen: updated temps via Consumer
            MLX90614Provider->>MLX90614Provider: Future.delayed(1s)
        end
    else device not connected
        MLX90614Screen-->>User: SnackBar Device not connected
    end

    User->>MLX90614Screen: navigate back
    MLX90614Screen->>MLX90614Provider: stopDataLog()
    deactivate MLX90614Provider
    deactivate MLX90614Screen
Loading

File-Level Changes

Change Details Files
Introduce MLX90614 I2C sensor driver to read ambient and object temperatures.
  • Create MLX90614 class that wraps an I2C instance with the default 0x5A device address.
  • Implement getAmbientTemperature and getObjectTemperature using a shared _readTemperature helper.
  • Use I2C.readBulk to read two bytes from ambient/object temperature registers, combine LSB/MSB, and convert the raw value to Celsius using the datasheet formula.
lib/communication/sensors/mlx90614.dart
Add MLX90614Provider to manage sensor lifecycle and periodic readings.
  • Create MLX90614Provider with ChangeNotifier, holding ambientTemp, objectTemp and an MLX90614 instance.
  • Implement init(I2C) to lazily construct the sensor, and startDataLog() as a guarded while(isWorking) loop that reads values every second with error handling.
  • Implement stopDataLog() to terminate the loop and notify listeners.
lib/providers/mlx90614_provider.dart
Add MLX90614 screen that initializes the sensor via locator, starts/stops polling, and displays readings.
  • Create MLX90614Screen as a StatefulWidget that, on first frame, resolves ScienceLab from getIt, constructs an I2C helper, initializes MLX90614Provider, and starts logging if the device is connected, otherwise shows a snackbar.
  • Ensure dispose() stops the data logging loop via the provider.
  • Build a simple UI with two cards (object temperature and ambient temperature), using Consumer to render formatted values.
lib/view/mlx90614_screen.dart
Wire MLX90614 provider and screen into app navigation and dependency injection.
  • Register MLX90614Provider as a lazy singleton in the service locator and expose it via ChangeNotifierProvider in main.dart.
  • Import MLX90614Screen into SensorsScreen and add a navigation case for sensor key 'MLX90614'.
  • Remove the problematic SHT21 import and switch statement case that were causing errors, leaving only the new MLX90614 entry for this PR.
lib/providers/locator.dart
lib/main.dart
lib/view/sensors_screen.dart
Update platform plugin registrants to include geolocator plugins (likely from pubspec changes).
  • Add geolocator_windows include and registration in the Windows generated plugin registrant and CMake plugin list.
  • Add geolocator_apple import and registration in the macOS generated plugin registrant.
windows/flutter/generated_plugin_registrant.cc
windows/flutter/generated_plugins.cmake
macos/Flutter/GeneratedPluginRegistrant.swift

Assessment against linked issues

Issue Objective Addressed Explanation
#2992 Implement low-level MLX90614 sensor communication over I2C (including reading ambient and object temperatures).
#2992 Add application-level state management for the MLX90614 sensor, including periodic data reading and error-safe looping.
#2992 Integrate the MLX90614 sensor into the app UI and navigation so users can view its readings from the Sensors screen.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • Remove in-code review notes and commented-out references (e.g., // Keep ONLY MLX90614 for this PR, // REMOVED: ... <-- Causing error) from SensorsScreen and related files to avoid leaving temporary review context and dead code in the main branch.
  • User-facing strings in MLX90614Screen (AppBar title, card titles, units, SnackBar text) should be wired through the existing localization system (AppLocalizations) instead of hard-coded literals for consistency with the rest of the app.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Remove in-code review notes and commented-out references (e.g., `// Keep ONLY MLX90614 for this PR`, `// REMOVED: ... <-- Causing error`) from `SensorsScreen` and related files to avoid leaving temporary review context and dead code in the main branch.
- User-facing strings in `MLX90614Screen` (AppBar title, card titles, units, SnackBar text) should be wired through the existing localization system (`AppLocalizations`) instead of hard-coded literals for consistency with the rest of the app.

## Individual Comments

### Comment 1
<location> `lib/communication/sensors/mlx90614.dart:39-46` </location>
<code_context>
+    int msb = data[1];
+
+    // Combine the bytes: (MSB << 8) | LSB
+    int rawValue = (msb << 8) | lsb;
+
+    // Formula from datasheet:
+    // The sensor returns temperature in Kelvin * 50.
+    // Multiply by 0.02 to get Kelvin.
+    // Subtract 273.15 to convert Kelvin to Celsius.
+    double tempCelsius = (rawValue * 0.02) - 273.15;
+
+    return tempCelsius;
</code_context>

<issue_to_address>
**suggestion:** The raw temperature value might benefit from masking out status bits per the MLX90614 datasheet before applying the conversion.

Per the MLX90614 datasheet, only the lower 15 bits represent the temperature; the MSB may contain status/flags. Currently `rawValue` uses all 16 bits, so status bits could skew the reading. Consider masking off the MSB before scaling:

```dart
int rawValue = ((msb << 8) | lsb) & 0x7FFF; // mask out status bit
double tempCelsius = (rawValue * 0.02) - 273.15;
```

```suggestion
    // Combine the bytes: (MSB << 8) | LSB and mask out status bit (only lower 15 bits are temperature)
    int rawValue = ((msb << 8) | lsb) & 0x7FFF;

    // Formula from datasheet:
    // The sensor returns temperature in Kelvin * 50.
    // Multiply by 0.02 to get Kelvin.
    // Subtract 273.15 to convert Kelvin to Celsius.
    double tempCelsius = (rawValue * 0.02) - 273.15;
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 5, 2026

Build Status

Build successful. APKs to test: https://github.com/fossasia/pslab-app/actions/runs/20708890390/artifacts/5021970006.

Screenshots

Android Screenshots
iPhone Screenshots
iPad Screenshots

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for sensor MLX90614

1 participant