From a32d5d2c854018e263f656e2c2e4f30873953470 Mon Sep 17 00:00:00 2001 From: Janez T Date: Thu, 19 Mar 2026 09:24:53 +0100 Subject: [PATCH] fix: Show irradiance values #123 --- ios/Runner.xcodeproj/project.pbxproj | 12 ++++---- ios/Runner/Info.plist | 2 +- ios/fastlane/report.xml | 8 +++--- .../sensors/sensor_telemetry_card.dart | 28 ++++++++++++------- pubspec.yaml | 2 +- test/widgets/contact_tile_test.dart | 10 +++---- .../sensor_metric_selector_item_test.dart | 12 ++++++-- test/widgets/sensor_telemetry_card_test.dart | 6 ++-- 8 files changed, 47 insertions(+), 33 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 9863ccf..c7e1106 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -489,7 +489,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 119; + CURRENT_PROJECT_VERSION = 121; DEVELOPMENT_TEAM = JND55328G8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -511,7 +511,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 119; + CURRENT_PROJECT_VERSION = 121; DEVELOPMENT_TEAM = JND55328G8; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; @@ -530,7 +530,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 119; + CURRENT_PROJECT_VERSION = 121; DEVELOPMENT_TEAM = JND55328G8; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; @@ -547,7 +547,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 119; + CURRENT_PROJECT_VERSION = 121; DEVELOPMENT_TEAM = JND55328G8; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; @@ -679,7 +679,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 119; + CURRENT_PROJECT_VERSION = 121; DEVELOPMENT_TEAM = JND55328G8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -702,7 +702,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 119; + CURRENT_PROJECT_VERSION = 121; DEVELOPMENT_TEAM = JND55328G8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 5f212e9..0c6e85f 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -43,7 +43,7 @@ CFBundleSignature ???? CFBundleVersion - 119 + 121 LSRequiresIPhoneOS ITSAppUsesNonExemptEncryption diff --git a/ios/fastlane/report.xml b/ios/fastlane/report.xml index 68c15a4..8ec34ed 100644 --- a/ios/fastlane/report.xml +++ b/ios/fastlane/report.xml @@ -5,22 +5,22 @@ - + - + - + - + diff --git a/lib/widgets/sensors/sensor_telemetry_card.dart b/lib/widgets/sensors/sensor_telemetry_card.dart index 1de7334..5b57ea5 100644 --- a/lib/widgets/sensors/sensor_telemetry_card.dart +++ b/lib/widgets/sensors/sensor_telemetry_card.dart @@ -211,8 +211,10 @@ List sensorMetricOptionsFor( // Skip them from extraSensorData to avoid duplicates. final coreFieldKeys = { if (batteryMilliVolts != null || batteryPercentage != null) - ...extraSensorData?.keys.where((k) => - k.startsWith('voltage_') || k.startsWith('analog_input_')) ?? [], + ...extraSensorData?.keys.where( + (k) => k.startsWith('voltage_') || k.startsWith('analog_input_'), + ) ?? + [], if (temperature != null) ...extraSensorData?.keys.where((k) => k.startsWith('temperature_')) ?? [], if (humidity != null) @@ -290,14 +292,14 @@ SensorMetricCardData? _buildOptionPreviewCardData( ); case 'illuminance': final lux = _previewAsDouble(value); + final irradiance = lux == null + ? null + : _previewFormatDaylightIrradiance(lux); return SensorMetricCardData( fieldKey: fieldKey, icon: Icons.light_mode_outlined, label: label, - value: previewValue, - secondaryValue: lux == null - ? null - : '~${_formatPreviewNumber(_previewApproxDaylightIrradiance(lux), maxFractionDigits: 1)} W/m2 daylight', + value: irradiance ?? previewValue, accent: const Color(0xFFC17B1D), channel: metricKey.channel, ); @@ -674,6 +676,10 @@ double _previewApproxDaylightIrradiance(double lux) { return lux / 120.0; } +String _previewFormatDaylightIrradiance(double lux) { + return '~${_formatPreviewNumber(_previewApproxDaylightIrradiance(lux), maxFractionDigits: 1)} W/m2'; +} + String _previewFormatCardinalDirection(double degrees) { const points = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']; final normalized = ((degrees % 360) + 360) % 360; @@ -699,7 +705,7 @@ String? _sensorMetricPreviewValue(String rawKey, dynamic value) { case 'illuminance': final lux = _previewAsDouble(value); if (lux == null) return null; - return '${_formatPreviewNumber(lux, maxFractionDigits: 0)} lx'; + return _previewFormatDaylightIrradiance(lux); case 'presence': final isPresent = _previewAsBool(value); @@ -1439,9 +1445,7 @@ class SensorTelemetryCard extends StatelessWidget { fieldKey: _extraFieldKey(rawKey), icon: Icons.light_mode_outlined, label: label, - value: '${_formatNumber(lux, maxFractionDigits: 0)} lx', - secondaryValue: - '~${_formatNumber(_approxDaylightIrradiance(lux), maxFractionDigits: 1)} W/m2 daylight', + value: _formatDaylightIrradiance(lux), accent: const Color(0xFFC17B1D), channel: metricKey.channel, ); @@ -1958,6 +1962,10 @@ class SensorTelemetryCard extends StatelessWidget { return lux / 120.0; } + String _formatDaylightIrradiance(double lux) { + return '~${_formatNumber(_approxDaylightIrradiance(lux), maxFractionDigits: 1)} W/m2'; + } + String _formatCurrent(double amps) { final absolute = amps.abs(); if (absolute < 1.0) { diff --git a/pubspec.yaml b/pubspec.yaml index a42b876..529885a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 2026.0317.1+33 +version: 2026.0318.1+34 environment: sdk: ^3.9.2 diff --git a/test/widgets/contact_tile_test.dart b/test/widgets/contact_tile_test.dart index b4774b3..5118c4e 100644 --- a/test/widgets/contact_tile_test.dart +++ b/test/widgets/contact_tile_test.dart @@ -164,18 +164,16 @@ void main() { expect(find.text('CO2'), findsOneWidget); expect(find.text('415 ppm'), findsOneWidget); expect(find.text('Illuminance'), findsOneWidget); - expect(find.text('~4.2 W/m2 daylight'), findsOneWidget); + expect(find.text('~4.2 W/m2'), findsOneWidget); + expect(find.textContaining('lx'), findsNothing); expect(find.text('Current'), findsOneWidget); expect(find.text('15 mA'), findsOneWidget); expect(find.text('Power'), findsOneWidget); expect(find.text('Distance'), findsOneWidget); - expect( - find.byKey(const ValueKey('sensor_metric_channel_battery')), - findsOneWidget, - ); + expect(find.byKey(const ValueKey('sensor_metric_battery')), findsOneWidget); expect(find.text('ch1'), findsWidgets); expect( - find.byKey(const ValueKey('sensor_metric_channel_extra:illuminance_2')), + find.byKey(const ValueKey('sensor_metric_extra:illuminance_2')), findsOneWidget, ); diff --git a/test/widgets/sensor_metric_selector_item_test.dart b/test/widgets/sensor_metric_selector_item_test.dart index dfb816d..8e2fe77 100644 --- a/test/widgets/sensor_metric_selector_item_test.dart +++ b/test/widgets/sensor_metric_selector_item_test.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:meshcore_sar_app/l10n/app_localizations.dart'; import 'package:meshcore_sar_app/screens/sensors_tab.dart'; import 'package:meshcore_sar_app/widgets/sensors/sensor_telemetry_card.dart'; @@ -7,6 +8,8 @@ void main() { testWidgets('renders selector previews and channel badges', (tester) async { await tester.pumpWidget( MaterialApp( + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, home: Scaffold( body: SensorMetricSelectorItem( option: const SensorMetricOption( @@ -14,12 +17,12 @@ void main() { label: 'Illuminance (ch 2)', defaultLabel: 'Illuminance', channel: 2, - valuePreview: '500 lx', + valuePreview: '~4.2 W/m2', previewCardData: SensorMetricCardData( fieldKey: 'extra:illuminance_2', icon: Icons.light_mode_outlined, label: 'Illuminance', - value: '500 lx', + value: '~4.2 W/m2', accent: Color(0xFFC17B1D), channel: 2, ), @@ -39,7 +42,8 @@ void main() { ); expect(find.text('Show on sensor card'), findsOneWidget); - expect(find.text('500 lx'), findsOneWidget); + expect(find.text('~4.2 W/m2'), findsOneWidget); + expect(find.textContaining('lx'), findsNothing); expect( find.byKey(const ValueKey('sensor_selector_channel_extra:illuminance_2')), findsOneWidget, @@ -50,6 +54,8 @@ void main() { testWidgets('omits duplicate channel chip for channel 1', (tester) async { await tester.pumpWidget( MaterialApp( + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, home: Scaffold( body: SensorMetricSelectorItem( option: const SensorMetricOption( diff --git a/test/widgets/sensor_telemetry_card_test.dart b/test/widgets/sensor_telemetry_card_test.dart index 262ebe0..fb31c3b 100644 --- a/test/widgets/sensor_telemetry_card_test.dart +++ b/test/widgets/sensor_telemetry_card_test.dart @@ -63,12 +63,14 @@ void main() { expect(find.text('Light'), findsOneWidget); expect(find.text('Temperature'), findsNothing); expect(find.text('Illuminance'), findsNothing); + expect(find.text('~4.2 W/m2'), findsOneWidget); + expect(find.textContaining('lx'), findsNothing); expect( - find.byKey(const ValueKey('sensor_metric_channel_temperature')), + find.byKey(const ValueKey('sensor_metric_temperature')), findsOneWidget, ); expect( - find.byKey(const ValueKey('sensor_metric_channel_extra:illuminance_2')), + find.byKey(const ValueKey('sensor_metric_extra:illuminance_2')), findsOneWidget, ); });