Skip to content

Commit ea12c9d

Browse files
2.1.0 Surface screen with last dive information support
1 parent e7c86a5 commit ea12c9d

11 files changed

+388
-69
lines changed

DiveIno/include/api/SerialApi.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
#include "DiveInoBase.h"
99
#include "utils/SettingsUtils.h"
1010
#include "utils/TimeUtils.h"
11+
#include "deco/LastDive.h"
1112

1213
class SerialApi : public DiveInoBase {
1314

1415
public:
15-
SerialApi(String versionNumber, SettingsUtils settingsUtils, TimeUtils timeUtils);
16+
SerialApi(String versionNumber, SettingsUtils settingsUtils, TimeUtils timeUtils, LastDive* lastDive);
1617

1718
bool isEmulatorEnabled();
1819
bool isReplayEnabled();
@@ -35,6 +36,8 @@ class SerialApi : public DiveInoBase {
3536

3637
SettingsUtils _settingsUtils;
3738
TimeUtils _timeUtils;
39+
40+
LastDive* _lastDive;
3841
};
3942

4043
#endif

DiveIno/include/deco/LastDive.h

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#ifndef LastDive_h
2+
#define LastDive_h
3+
4+
#include "Arduino.h"
5+
#include "Preferences.h"
6+
#include "M5ez.h"
7+
#include "ezTime.h"
8+
9+
#include "deco/Buhlmann.h"
10+
11+
#define COMPARTMENT_COUNT 16
12+
13+
struct LastDiveData {
14+
long diveDateTimestamp = 0;
15+
float maxDepthInMeters = 0.0;
16+
int durationInSeconds = 0;
17+
long noFlyTimeInMinutes = 0;
18+
bool wasDecoDive = false;
19+
float compartmentPartialPressures[COMPARTMENT_COUNT];
20+
};
21+
22+
class LastDive {
23+
public:
24+
LastDiveData* loadLastDiveData();
25+
void storeLastDiveData(LastDiveData* lastDiveData);
26+
bool clearLastDiveData();
27+
28+
long getNoFlyTimeInMinutes();
29+
long getCurrentSurfaceIntervalInMinutes();
30+
DiveResult* spendTimeOnSurface(int surfaceIntervalInMinutes, Buhlmann* buhlmann);
31+
private:
32+
void _debugLastDiveData(LastDiveData* lastDiveData);
33+
};
34+
35+
#endif

DiveIno/include/screens/DiveScreen.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "screens/DiveInoScreen.h"
99
#include "deco/Buhlmann.h"
10+
#include "deco/LastDive.h"
1011

1112
#define SAFE_MODE 510
1213
#define SAFETY_STOP_MODE 520
@@ -21,7 +22,7 @@
2122
class DiveScreen : public DiveInoScreen {
2223

2324
public:
24-
DiveScreen(Buhlmann* buhlmann);
25+
DiveScreen(Buhlmann* buhlmann, LastDive* lastDive);
2526

2627
void init(DiveInoSettings diveInoSettings, PressureSensorData sensorData, bool replayEnabled, bool emulatorEnabled);
2728

@@ -43,6 +44,8 @@ class DiveScreen : public DiveInoScreen {
4344

4445
private:
4546
Buhlmann* _buhlmann;
47+
LastDive* _lastDive;
48+
4649
DiveInoSettings _diveInoSettings;
4750
int _currentMode = SAFE_MODE;
4851
bool _diveStarted = false;

DiveIno/include/screens/HomeScreen.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77

88
#include "screens/DiveInoScreen.h"
99
#include "utils/TimeUtils.h"
10+
#include "deco/LastDive.h"
1011

1112
class HomeScreen : public DiveInoScreen {
1213

1314
public:
14-
HomeScreen(TimeUtils timeUtils);
15+
HomeScreen(TimeUtils timeUtils, LastDive* lastDive);
1516
void initHomeScreen(DiveInoSettings diveInoSettings);
1617

1718
void displayHomeClock();
@@ -22,6 +23,9 @@ class HomeScreen : public DiveInoScreen {
2223
int handleButtonPress(String buttonName);
2324

2425
private:
26+
LastDive* _lastDive;
27+
bool _isNoFlyDisplayed();
28+
2529
bool _isMinimalModeActive = false;
2630
DiveInoSettings _diveInoSettings;
2731
TimeUtils _timeUtils;

DiveIno/include/screens/SurfaceScreen.h

+11-5
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,22 @@
77

88
#include "screens/DiveInoScreen.h"
99
#include "deco/Buhlmann.h"
10+
#include "deco/LastDive.h"
1011

1112
class SurfaceScreen : public DiveInoScreen {
1213

1314
public:
14-
void init(DiveInoSettings diveInoSettings, DiveResult* diveResult);
15+
void init(DiveInoSettings diveInoSettings, LastDiveData* lastDiveData);
1516
void handleButtonPress(String buttonName);
16-
private:
17-
DiveResult* _diveResult;
18-
DiveInoSettings _diveInoSettings;
19-
void _display();
17+
void display();
18+
private:
19+
DiveInoSettings _diveInoSettings;
20+
LastDive* _lastDive;
21+
LastDiveData* _lastDiveData = NULL;
22+
23+
long _calculateNoFlyTime(LastDiveData* lastDiveData);
24+
long _calculateSurfaceInterval(LastDiveData* lastDiveData);
25+
void _displaySurfaceInterval(unsigned long elapsedTimeInSeconds);
2026
};
2127

2228
#endif

DiveIno/src/api/SerialApi.cpp

+13-14
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
// Serial API //
55
////////////////
66

7-
SerialApi::SerialApi(String versionNumber, SettingsUtils settingsUtils, TimeUtils timeUtils)
7+
SerialApi::SerialApi(String versionNumber, SettingsUtils settingsUtils, TimeUtils timeUtils, LastDive* lastDive)
88
{
99
_versionNumber = versionNumber;
1010
_settingsUtils = settingsUtils;
1111
_timeUtils = timeUtils;
12+
_lastDive = lastDive;
1213
}
1314

1415
void SerialApi::updatePressureSensorData(PressureSensorData sensorData)
@@ -233,25 +234,23 @@ void SerialApi::handleMessage(String message)
233234
responseMessage += F("#");
234235
outputStream->println(responseMessage);
235236
} else if (message.startsWith(F("CLEAR")) || message.startsWith(F("clear"))) {
236-
//TODO Remove last dive information
237-
// if (lastDive.clearLastDiveData()) {
238-
// responseMessage += F("CLEAR - OK");
239-
// } else {
240-
// responseMessage += F("ERROR: Surface time clean operation failed!");
241-
// }
237+
if (_lastDive->clearLastDiveData()) {
238+
responseMessage += F("CLEAR - OK");
239+
} else {
240+
responseMessage += F("ERROR: Surface time clean operation failed!");
241+
}
242242
responseMessage += F("#");
243243
outputStream->println(responseMessage);
244244
} else if (message.startsWith(F("RESET")) || message.startsWith(F("reset"))) {
245245
//Revert settings to default
246246
responseMessage += F("SETTINGS - Default settings will be restored.\n");
247247
_settingsUtils.resetSettings();
248-
249-
//TODO Remove last dive information
250-
// if (lastDive.clearLastDiveData()) {
251-
// responseMessage += F("LAST DIVE - Last dive information was deleted.\n");
252-
// } else {
253-
// responseMessage += F("ERROR: Failed to delete last dive information!\n");
254-
// }
248+
249+
if (_lastDive->clearLastDiveData()) {
250+
responseMessage += F("LAST DIVE - Last dive information was deleted.\n");
251+
} else {
252+
responseMessage += F("ERROR: Failed to delete last dive information!\n");
253+
}
255254

256255
//TODO Remove all dive profile files
257256
// if (logbook.clearProfiles()) {

DiveIno/src/deco/LastDive.cpp

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#include "deco/LastDive.h"
2+
3+
void LastDive::_debugLastDiveData(LastDiveData* lastDiveData)
4+
{
5+
Serial.print("lDate: ");
6+
Serial.println(lastDiveData->diveDateTimestamp);
7+
Serial.print("lMaxDepth: ");
8+
Serial.println(lastDiveData->maxDepthInMeters);
9+
Serial.print("lDur: ");
10+
Serial.println(lastDiveData->durationInSeconds);
11+
Serial.print("lNoFly: ");
12+
Serial.println(lastDiveData->noFlyTimeInMinutes);
13+
Serial.print("lDeco: ");
14+
Serial.println(lastDiveData->wasDecoDive);
15+
16+
for (int i=0; i<COMPARTMENT_COUNT; i++) {
17+
Serial.print("lComp");
18+
Serial.print(i);
19+
Serial.print(" : ");
20+
Serial.println(lastDiveData->compartmentPartialPressures[i]);
21+
}
22+
}
23+
24+
LastDiveData* LastDive::loadLastDiveData()
25+
{
26+
LastDiveData* lastDiveData = new LastDiveData;
27+
28+
Preferences prefs;
29+
prefs.begin("DiveIno", true); // read-only
30+
31+
lastDiveData->diveDateTimestamp = prefs.getLong("lDate", ez.clock.tz.now());
32+
lastDiveData->maxDepthInMeters = prefs.getFloat("lMaxDepth", 0.0);
33+
lastDiveData->durationInSeconds = prefs.getInt("lDur", 0);
34+
lastDiveData->noFlyTimeInMinutes = prefs.getLong("lNoFly" , 0);
35+
lastDiveData->wasDecoDive = prefs.getBool("lDeco", false);
36+
37+
for (int i=0; i<COMPARTMENT_COUNT; i++) {
38+
lastDiveData->compartmentPartialPressures[i] = prefs.getFloat("lComp" + i, 0.0);
39+
}
40+
41+
prefs.end();
42+
43+
Serial.println("LOAD Last Dive Data");
44+
this->_debugLastDiveData(lastDiveData);
45+
46+
return lastDiveData;
47+
}
48+
49+
void LastDive::storeLastDiveData(LastDiveData* lastDiveData)
50+
{
51+
Preferences prefs;
52+
prefs.begin("DiveIno");
53+
54+
prefs.putLong("lDate", lastDiveData->diveDateTimestamp);
55+
prefs.putFloat("lMaxDepth", lastDiveData->maxDepthInMeters);
56+
prefs.putInt("lDur", lastDiveData->durationInSeconds);
57+
prefs.putLong("lNoFly" , lastDiveData->noFlyTimeInMinutes);
58+
prefs.putBool("lDeco", lastDiveData->wasDecoDive);
59+
60+
for (int i=0; i<COMPARTMENT_COUNT; i++) {
61+
prefs.putFloat("lComp" + i, lastDiveData->compartmentPartialPressures[i]);
62+
}
63+
64+
prefs.end();
65+
66+
Serial.println("STORE Last Dive Data");
67+
this->_debugLastDiveData(lastDiveData);
68+
}
69+
70+
bool LastDive::clearLastDiveData()
71+
{
72+
Preferences prefs;
73+
prefs.begin("DiveIno");
74+
75+
prefs.remove("lDate");
76+
prefs.remove("lMaxDepth");
77+
prefs.remove("lDur");
78+
prefs.remove("lNoFly");
79+
prefs.remove("lDeco");
80+
81+
for (int i=0; i<COMPARTMENT_COUNT; i++) {
82+
prefs.remove("lComp" + i);
83+
}
84+
85+
prefs.end();
86+
87+
Serial.println("CLEAR Last Dive Data");
88+
89+
return true;
90+
}
91+
92+
long LastDive::getNoFlyTimeInMinutes()
93+
{
94+
Preferences prefs;
95+
prefs.begin("DiveIno", true); // read-only
96+
long noFlyTime = prefs.getLong("lNoFly" , 0L);
97+
prefs.end();
98+
99+
return noFlyTime;
100+
}
101+
102+
long LastDive::getCurrentSurfaceIntervalInMinutes()
103+
{
104+
long nowTimestamp = ez.clock.tz.now();
105+
106+
Preferences prefs;
107+
prefs.begin("DiveIno", true); // read-only
108+
long diveDateTimestamp = prefs.getLong("lDate", nowTimestamp);
109+
prefs.end();
110+
111+
//Calculate surface interval
112+
return (nowTimestamp - diveDateTimestamp) / 60;
113+
}
114+
115+
DiveResult* LastDive::spendTimeOnSurface(int surfaceIntervalInMinutes, Buhlmann* buhlmann)
116+
{
117+
DiveResult* diveResult = new DiveResult;
118+
diveResult = buhlmann->initializeCompartments();
119+
120+
//Retrieve last dive data
121+
LastDiveData* lastDiveData = this->loadLastDiveData();
122+
123+
long nowTimestamp = ez.clock.tz.now();
124+
125+
//Last dive happened within 48 hours and there is an active no fly time
126+
if (lastDiveData != NULL && (lastDiveData->diveDateTimestamp + 172800) > nowTimestamp && lastDiveData->noFlyTimeInMinutes > 0) {
127+
128+
Serial.print(F("BEFORE dive No Fly time (min): "));
129+
Serial.println(lastDiveData->noFlyTimeInMinutes);
130+
131+
//Copy Last Dive Data
132+
diveResult->noFlyTimeInMinutes = lastDiveData->noFlyTimeInMinutes;
133+
diveResult->previousDiveDateTimestamp = lastDiveData->diveDateTimestamp;
134+
diveResult->wasDecoDive = lastDiveData->wasDecoDive;
135+
for (byte i=0; i <COMPARTMENT_COUNT; i++) {
136+
diveResult->compartmentPartialPressures[i] = lastDiveData->compartmentPartialPressures[i];
137+
138+
Serial.print(F("BEFORE: Dive compartment "));
139+
Serial.print(i);
140+
Serial.print(F(": "));
141+
Serial.print(diveResult->compartmentPartialPressures[i], 0);
142+
Serial.println(F(" ppN2"));
143+
}
144+
145+
//Calculate surface time in minutes
146+
int surfaceTime = (nowTimestamp - lastDiveData->diveDateTimestamp) / 60;
147+
148+
Serial.print(F("Surface time (min): "));
149+
Serial.println(surfaceTime);
150+
151+
//Spend the time on the surface
152+
diveResult = buhlmann->surfaceInterval(surfaceTime, diveResult);
153+
154+
for (byte i=0; i <COMPARTMENT_COUNT; i++) {
155+
Serial.print(F("AFTER: Dive compartment "));
156+
Serial.print(i);
157+
Serial.print(F(": "));
158+
Serial.print(diveResult->compartmentPartialPressures[i], 0);
159+
Serial.println(F(" ppN2"));
160+
}
161+
162+
Serial.print(F("AFTER dive No Fly time (min): "));
163+
Serial.println(diveResult->noFlyTimeInMinutes);
164+
}
165+
return diveResult;
166+
}

0 commit comments

Comments
 (0)