Skip to content
4 changes: 3 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -346,5 +346,7 @@
"gyroscopeHighLimitHint" : "Please provide the maximum limit of lux value to be recorded (0 rad/s to 1000 rad/s)",
"accelerometerConfigurations" : "Accelerometer Configurations",
"accelerometerUpdatePeriodHint" : "Please provide time interval at which data will be updated",
"accelerometerHighLimitHint" : "Please provide the maximum limit of lux value to be recorded"
"accelerometerHighLimitHint" : "Please provide the maximum limit of lux value to be recorded",
"soundmeterSnackBarMessage" : "Unable to access sound sensor",
"dangerous" : "Dangerous"
}
12 changes: 12 additions & 0 deletions lib/l10n/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2175,6 +2175,18 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Please provide the maximum limit of lux value to be recorded'**
String get accelerometerHighLimitHint;

/// No description provided for @soundmeterSnackBarMessage.
///
/// In en, this message translates to:
/// **'Unable to access sound sensor'**
String get soundmeterSnackBarMessage;

/// No description provided for @dangerous.
///
/// In en, this message translates to:
/// **'Dangerous'**
String get dangerous;
}

class _AppLocalizationsDelegate
Expand Down
7 changes: 7 additions & 0 deletions lib/l10n/app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,7 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get fileDeleted => 'File deleted';

@override
String get soundmeterConfig => 'Soundmeter Configurations';

@override
Expand Down Expand Up @@ -1114,4 +1115,10 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get accelerometerHighLimitHint =>
'Please provide the maximum limit of lux value to be recorded';

@override
String get soundmeterSnackBarMessage => 'Unable to access sound sensor';

@override
String get dangerous => 'Dangerous';
}
11 changes: 6 additions & 5 deletions lib/providers/luxmeter_state_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class LuxMeterStateProvider extends ChangeNotifier {
bool _sensorAvailable = false;
bool _isRecording = false;
List<List<dynamic>> _recordedData = [];
double _recordingStartTime = 0.0;
bool get isRecording => _isRecording;

LuxMeterConfigProvider? _configProvider;
Expand Down Expand Up @@ -112,13 +111,14 @@ class LuxMeterStateProvider extends ChangeNotifier {
final time = _currentTime;
if (lux != null) {
if (_isRecording) {
final relativeTime = time - _recordingStartTime;
final now = DateTime.now();
final dateFormat = DateFormat('yyyy-MM-dd HH:mm:ss.SSS');
_recordedData.add([
now.millisecondsSinceEpoch.toString(),
dateFormat.format(now),
relativeTime.toStringAsFixed(2),
lux.toStringAsFixed(2),
0,
0
]);
}

Expand Down Expand Up @@ -146,8 +146,9 @@ class LuxMeterStateProvider extends ChangeNotifier {

void startRecording() {
_isRecording = true;
_recordingStartTime = _currentTime;
_recordedData = [];
_recordedData = [
['Timestamp', 'DateTime', 'Readings', 'Latitude', 'Longitude']
];
notifyListeners();
}

Expand Down
45 changes: 42 additions & 3 deletions lib/providers/soundmeter_state_provider.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import 'package:intl/intl.dart';
import 'package:pslab/l10n/app_localizations.dart';
import 'package:pslab/others/logger_service.dart';
import 'package:flutter/foundation.dart';
Expand All @@ -18,13 +19,20 @@ class SoundMeterStateProvider extends ChangeNotifier {
AudioJack? _audioJack;
double _startTime = 0;
double _currentTime = 0;
final int _maxLength = 50;
final int _chartMaxLength = 50;
double _dbMin = 0;
double _dbMax = 0;
double _dbSum = 0;
int _dataCount = 0;
bool _isRecording = false;
List<List<dynamic>> _recordedData = [];
bool get isRecording => _isRecording;

Function(String)? onSensorError;

void initializeSensors({Function(String)? onError}) async {
onSensorError = onError;

void initializeSensors() async {
try {
_audioJack = AudioJack();
await _audioJack!.initialize();
Expand All @@ -50,9 +58,15 @@ class SoundMeterStateProvider extends ChangeNotifier {
});
} catch (e) {
logger.e("${appLocalizations.soundMeterInitialError} $e");
_handleSensorError(e);
}
}

void _handleSensorError(dynamic error) {
onSensorError?.call(appLocalizations.soundmeterSnackBarMessage);
logger.e("${appLocalizations.soundMeterInitialError} $error");
}

double _calculateDecibels(List<double> audioData) {
if (audioData.isEmpty) return 0.0;

Expand Down Expand Up @@ -87,11 +101,22 @@ class SoundMeterStateProvider extends ChangeNotifier {
void _updateData() {
final db = _currentDb;
final time = _currentTime;
if (_isRecording) {
final now = DateTime.now();
final dateFormat = DateFormat('yyyy-MM-dd HH:mm:ss.SSS');
_recordedData.add([
now.millisecondsSinceEpoch.toString(),
dateFormat.format(now),
db.toStringAsFixed(2),
0,
0
]);
}
_dbData.add(db);
_timeData.add(time);
_dbSum += db;
_dataCount++;
if (_dbData.length > _maxLength) {
if (_dbData.length > _chartMaxLength) {
final removedValue = _dbData.removeAt(0);
_timeData.removeAt(0);
_dbSum -= removedValue;
Expand All @@ -108,6 +133,20 @@ class SoundMeterStateProvider extends ChangeNotifier {
notifyListeners();
}

void startRecording() {
_isRecording = true;
_recordedData = [
['Timestamp', 'DateTime', 'Readings', 'Latitude', 'Longitude']
];
notifyListeners();
}

List<List<dynamic>> stopRecording() {
_isRecording = false;
notifyListeners();
return _recordedData;
}

double getCurrentDb() => _currentDb;
double getMinDb() => _dbMin;
double getMaxDb() => _dbMax;
Expand Down
63 changes: 47 additions & 16 deletions lib/view/logged_data_chart_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class LoggedDataChartScreen extends StatefulWidget {
required this.fileName,
this.xAxisLabel = 'Time (s)',
this.yAxisLabel = 'Value',
this.xDataColumnIndex = 1,
this.xDataColumnIndex = 0,
this.yDataColumnIndex = 2,
});

Expand Down Expand Up @@ -105,18 +105,7 @@ class _LoggedDataChartScreenState extends State<LoggedDataChartScreen> {
sideTitles: SideTitles(
showTitles: true,
reservedSize: reservedSizeBottom,
getTitlesWidget: (value, meta) {
return SideTitleWidget(
meta: meta,
child: Text(
value.toStringAsFixed(1),
style: TextStyle(
color: blackTextColor,
fontSize: chartFontSize,
),
),
);
},
getTitlesWidget: _sideTitleWidgets,
interval: timeInterval,
),
),
Expand Down Expand Up @@ -195,6 +184,7 @@ class _LoggedDataChartScreenState extends State<LoggedDataChartScreen> {
double maxY = 0;
double maxX = 0;
double minX = 0;
double? startTime;

for (int i = 1; i < widget.data.length; i++) {
final row = widget.data[i];
Expand All @@ -204,10 +194,16 @@ class _LoggedDataChartScreenState extends State<LoggedDataChartScreen> {
final yValue = _parseDouble(row[widget.yDataColumnIndex]);

if (xValue != null && yValue != null) {
spots.add(FlSpot(xValue, yValue));
if (startTime == null) {
startTime = xValue;
minX = 0;
}

final relativeTime = ((xValue - startTime) / 1000.0);

spots.add(FlSpot(relativeTime, yValue));
if (yValue > maxY) maxY = yValue;
if (xValue > maxX) maxX = xValue;
if (spots.length == 1 || xValue < minX) minX = xValue;
if (relativeTime > maxX) maxX = relativeTime;
}
}
}
Expand Down Expand Up @@ -252,4 +248,39 @@ class _LoggedDataChartScreenState extends State<LoggedDataChartScreen> {
),
);
}

Widget _sideTitleWidgets(double value, TitleMeta meta) {
final screenWidth = MediaQuery.of(context).size.width;
final fontSize = screenWidth < 400
? 7.0
: screenWidth < 600
? 8.0
: 9.0;
final style = TextStyle(
color: blackTextColor,
fontSize: fontSize,
);

String timeText;
if (value < 60) {
timeText = '${value.toInt()}s';
} else if (value < 3600) {
int minutes = (value / 60).floor();
int seconds = (value % 60).toInt();
timeText = '${minutes}m${seconds}s';
} else {
int hours = (value / 3600).floor();
int minutes = ((value % 3600) / 60).floor();
timeText = '${hours}h${minutes}m';
}

return SideTitleWidget(
meta: meta,
child: Text(
maxLines: 1,
timeText,
style: style,
),
);
}
}
4 changes: 2 additions & 2 deletions lib/view/logged_data_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ class _LoggedDataScreenState extends State<LoggedDataScreen> {
return {
'xAxisLabel': appLocalizations.timeAxisLabel,
'yAxisLabel': appLocalizations.lx,
'xDataColumnIndex': 1,
'xDataColumnIndex': 0,
'yDataColumnIndex': 2,
};
case 'soundmeter':
return {
'xAxisLabel': appLocalizations.timeAxisLabel,
'yAxisLabel': appLocalizations.db,
'xDataColumnIndex': 1,
'xDataColumnIndex': 0,
'yDataColumnIndex': 2,
};
case 'barometer':
Expand Down
Loading
Loading