Skip to content

Commit 593f391

Browse files
committed
logger core initial files
1 parent 41d0134 commit 593f391

6 files changed

Lines changed: 546 additions & 0 deletions

File tree

LoggerCore/src/LoggerPlatform.h

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#pragma once
2+
3+
#include "Particle.h"
4+
5+
// file helper to get at flash system usage
6+
// dependencies.FileHelperRK=0.0.3
7+
#include "FileHelperRK.h"
8+
9+
namespace LoggerPlatform {
10+
11+
// wifi
12+
#if (PLATFORM_ID == PLATFORM_PHOTON || PLATFORM_ID == PLATFORM_ARGON || PLATFORM_ID == PLATFORM_P2)
13+
const bool wifi = true;
14+
#else
15+
const bool wifi = false;
16+
#endif
17+
const bool hasWifi() { return wifi; };
18+
19+
// cellular
20+
#if (PLATFORM_ID == PLATFORM_BORON)
21+
const bool cellular = true;
22+
#else
23+
const bool cellular = false;
24+
#endif
25+
const bool hasCellular() { return cellular; };
26+
27+
// byte size constants
28+
const size_t B = 1;
29+
const size_t KB = 1024;
30+
const size_t MB = 1024 * 1024;
31+
32+
// flash memory (in bytes)
33+
#if (PLATFORM_ID == PLATFORM_ARGON || PLATFORM_ID == PLATFORM_P2 || PLATFORM_ID == PLATFORM_BORON)
34+
const size_t flash_size = 2 * MB;
35+
#else
36+
const size_t flash_size = 0;
37+
#endif
38+
const bool hasFlash() { return (flash_size > 0); };
39+
const float getTotalFlash(const size_t units = B);
40+
float getUsedFlash(const size_t units = B);
41+
float getFreeFlash(const size_t units = B);
42+
float getFreeFlashPercent();
43+
44+
// flash sectors
45+
const size_t sector_size = 4 * KB;
46+
const size_t flash_sectors = flash_size / sector_size; // available sectors
47+
48+
// random access memory / RAM (in bytes) that is available to the user application
49+
#if (PLATFORM_ID == PLATFORM_PHOTON)
50+
const size_t ram_size = 60 * KB; // approximate
51+
#elif (PLATFORM_ID == PLATFORM_ARGON || PLATFORM_ID == PLATFORM_BORON)
52+
const size_t ram_size = 80 * KB; // approximate
53+
#elif (PLATFORM_ID == PLATFORM_P2)
54+
const size_t ram_size = 3 * MB; // approximate
55+
#else
56+
const size_t ram_size = 0;
57+
#endif
58+
const float getTotalRAM(const size_t units = B);
59+
float getUsedRAM(const size_t units = B);
60+
float getFreeRAM(const size_t units = B);
61+
float getFreeRAMPercent();
62+
63+
// info
64+
Variant getSystemStatus();
65+
66+
}
67+
68+
/*** implementation ***/
69+
70+
// flash functions
71+
const float LoggerPlatform::getTotalFlash(const size_t units) {
72+
return( (float) flash_size/units);
73+
}
74+
float LoggerPlatform::getUsedFlash(const size_t units) {
75+
if (!hasFlash()) return (0.0);
76+
FileHelperRK::Usage usage;
77+
usage.measure("/");
78+
return( (float) (usage.sectors * sector_size) / units);
79+
}
80+
float LoggerPlatform::getFreeFlash(const size_t units) {
81+
if (!hasFlash()) return (0.0);
82+
return( (getTotalFlash() - getUsedFlash())/units);
83+
};
84+
float LoggerPlatform::getFreeFlashPercent() {
85+
if (!hasFlash()) return(NAN);
86+
return(100. * getFreeFlash() / getTotalFlash());
87+
};
88+
89+
// RAM functions
90+
const float LoggerPlatform::getTotalRAM(const size_t units) {
91+
return( (float) ram_size/units);
92+
}
93+
float LoggerPlatform::getUsedRAM(const size_t units) {
94+
return((getTotalRAM() - getFreeRAM()) / units);
95+
}
96+
float LoggerPlatform::getFreeRAM(const size_t units) {
97+
return((float) System.freeMemory()/units);
98+
};
99+
float LoggerPlatform::getFreeRAMPercent() {
100+
return(100. * getFreeRAM() / getTotalRAM());
101+
};
102+
103+
// system status
104+
Variant LoggerPlatform::getSystemStatus() {
105+
Variant sys;
106+
sys.set("firmware", System.version());
107+
sys.set("id", System.deviceID());
108+
sys.set("wifi", hasWifi());
109+
sys.set("cell", hasCellular());
110+
Variant mem;
111+
mem.set("total", getTotalRAM());
112+
mem.set("used", getUsedRAM());
113+
sys.set("RAM", mem);
114+
Variant flash;
115+
flash.set("total", getTotalFlash());
116+
flash.set("used", getUsedFlash());
117+
sys.set("flash", flash);
118+
return(sys);
119+
}

LoggerCore/src/LoggerPublisher.cpp

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
#include "Particle.h"
2+
#include "LoggerPublisher.h"
3+
4+
bool LoggerPublisher::publish(const Variant &data) {
5+
return(true);
6+
// if (!event.isNew()) {
7+
// // an event is already being sent --> need to queue it
8+
// }
9+
10+
// // set up event
11+
// m_event.name(m_event_name);
12+
// m_event.data(data);
13+
14+
// // can we publish?
15+
// if (!CloudEvent::canPublish(m_event.size())) {
16+
// return(false);
17+
// }
18+
19+
// _log.trace("publishing fileNum=%d event=%s", curFileNum, curEvent.name());
20+
21+
// if (!Particle.publish(m_event)) {
22+
// Log.error("published failed immediately, discarding");
23+
// deleteCurEvent();
24+
// stateHandler = &PublishQueueExt::stateWaitEvent;
25+
// durationMs = waitBetweenPublish;
26+
// return;
27+
// }
28+
29+
30+
// //return publish(event);
31+
// return publish(m_event);
32+
}
33+
34+
void LoggerPublisher::queueData(const Variant &data) {
35+
m_burst_ongoing = true;
36+
m_last_burst_data = millis();
37+
m_burst_data.append(data);
38+
}
39+
40+
void LoggerPublisher::queueBurst() {
41+
Variant burst;
42+
if (DeviceNameHelperEEPROM::instance().hasName()) {
43+
// device name is available
44+
burst.set("id", DeviceNameHelperEEPROM::instance().getName());
45+
} else {
46+
// no device name available -- use device ID instead
47+
burst.set("id", System.deviceID());
48+
}
49+
burst.set("b", m_burst_data);
50+
Log.trace("adding burst to queue: %s", burst.toJSON().c_str());
51+
m_data_queue.append(burst);
52+
m_burst_data.clear();
53+
54+
// sd backup
55+
if (m_use_sd_backup) {
56+
Log.trace("backing up burst on SD card in file %s", m_sd_log_file.c_str());
57+
if (m_sd->available()) {
58+
m_sd->append(m_sd_log_file.c_str());
59+
m_sd->println(burst.toJSON().c_str());
60+
m_sd->syncFile();
61+
} else {
62+
Log.error("SD card unavailable, burst could not be backed up");
63+
}
64+
}
65+
66+
// } else if (System.freeMemory() < memory_reserve) {
67+
// out_of_memory = true;
68+
// Serial.printlnf("WARNING: state log '%s' NOT queued because free memory < memory reserve (%d bytes).", state_log, memory_reserve);
69+
// saveStateLogToSD(); // check for SD save even if we're out of RAM
70+
// } else {
71+
}
72+
73+
// setup and loop
74+
75+
void LoggerPublisher::setup() {
76+
if(m_use_sd_backup) {
77+
Log.info("starting logger (with SD backup)");
78+
m_sd->init();
79+
} else {
80+
Log.info("starting logger (without SD backup)");
81+
}
82+
m_sd_log_file = String::format("device_%s.log", System.deviceID().c_str());
83+
}
84+
85+
void LoggerPublisher::loop() {
86+
87+
// check for end of a data burst
88+
if (m_burst_ongoing && (millis() - m_last_burst_data) > m_wait_for_burst_data) {
89+
queueBurst();
90+
m_burst_ongoing = false;
91+
}
92+
93+
// check on publish state
94+
switch(m_publish_state) {
95+
96+
// waiting to connect
97+
case State::WAIT_CONNECT:
98+
if (Particle.connected()) {
99+
// connected!
100+
m_state_time = millis();
101+
m_publish_state = State::WAIT_PUBLISH;
102+
} else if ( !m_data_queue.isEmpty()) {
103+
// we've got data but no connection --> store on disc
104+
105+
}
106+
break;
107+
108+
// waiting for event
109+
case State::WAIT_PUBLISH:
110+
if (!Particle.connected()) {
111+
// disconnected!
112+
m_publish_state = State::WAIT_CONNECT;
113+
} else if ( !m_data_queue.isEmpty() &&
114+
(millis() - m_state_time) > m_wait_after_connect) {
115+
// we've got data and a stable connection
116+
117+
}
118+
break;
119+
120+
121+
// case State::START:
122+
// if (Particle.connected() && ((lastPublish == 0) || (millis() - lastPublish >= publishPeriod.count()))) {
123+
// lastPublish = millis();
124+
// state = State::SEND;
125+
// }
126+
// break;
127+
128+
129+
130+
131+
// case State::SEND:
132+
// state = State::START;
133+
// if (publishSensors()) {
134+
// state = State::WAIT_COMPLETION;
135+
// }
136+
// break;
137+
138+
// case State::WAIT_COMPLETION:
139+
// if (event.isSent()) {
140+
// Log.info("publish succeeded");
141+
// state = State::START;
142+
// }
143+
// else
144+
// if (!event.isOk()) {
145+
// Log.info("publish failed error=%d", event.error());
146+
// state = State::START;
147+
// }
148+
// break;
149+
}
150+
151+
152+
// // nothing to do if event is new or still sending
153+
// if (m_event.isNew() || m_event.isSending()) {
154+
// return;
155+
// }
156+
157+
// if (event.isSent()) {
158+
// Log.info("publish succeeded");
159+
// stateHandler = &SensorPublish::start;
160+
// return;
161+
// }
162+
// if (!event.isOk()) {
163+
// Log.info("publish failed error=%d", event.error());
164+
// stateHandler = &SensorPublish::start;
165+
// return;
166+
// }
167+
168+
// if (!m_event.isValid()) {
169+
// _log.trace("publish failed invalid %d (discarding)", curFileNum);
170+
// m_event.clear();
171+
// } else if (m_event.isSent()) {
172+
// _log.trace("publish success %d", curFileNum);
173+
// m_event.clear();
174+
// }
175+
// else {
176+
// _log.trace("publish failed %d (retrying)", curFileNum);
177+
// curFileNum = 0;
178+
// durationMs = waitAfterFailure;
179+
// }
180+
181+
// if (curEvent.isSending()) {
182+
// // Stay in statePublishWait
183+
// return;
184+
// }
185+
}
186+
187+
// sd functions
188+
void LoggerPublisher::useSdBackup(bool use) {
189+
if (!m_use_sd_backup && use)
190+
Log.info("logger turning on SD backup");
191+
else if (m_use_sd_backup && !use)
192+
Log.info("logger turning off SD backup");
193+
m_use_sd_backup = use;
194+
};
195+
196+
bool LoggerPublisher::testSD() {
197+
Log.info("running SD write/read test");
198+
199+
// check enabled
200+
if (!m_use_sd_backup) {
201+
Log.error("cannot test SD, logger is not using SD backup");
202+
return(false);
203+
}
204+
205+
// check available
206+
if (!m_sd->available()) {
207+
Log.error("cannot test SD, SD card is not available");
208+
return(false);
209+
}
210+
211+
// remove previous test file if still there
212+
long file_size = m_sd->size("sd_test.txt");
213+
if (file_size > -1) {
214+
Log.info("deleting test file from previous test");
215+
m_sd->removeFile("sd_test.txt");
216+
217+
// check if it's been deleted
218+
if (m_sd->size("sd_test.txt") > -1) {
219+
Log.error("could not remove previous test file from SD card");
220+
return(false);
221+
}
222+
}
223+
224+
// write test file
225+
Log.info("writing test file sd_test.txt");
226+
m_sd->append("sd_test.txt");
227+
m_sd->print("test");
228+
m_sd->syncFile();
229+
230+
// now should have test file
231+
if (m_sd->size("sd_test.txt") == -1) {
232+
Log.error("could not write test file to SD card");
233+
return(false);
234+
}
235+
236+
// read back test file
237+
Log.info("reading back test file sd_test.txt");
238+
byte buffer[4] = {0, 0, 0, 0};
239+
m_sd->read(buffer, 4, "sd_test.txt");
240+
if (buffer[0] != 't' || buffer[1] != 'e' || buffer[2] != 's' || buffer[3] != 't') {
241+
Log.error("could not confirm correct test file contents");
242+
return(false);
243+
}
244+
245+
Log.info("successfully recovered file content, SD card test complete");
246+
return(true);
247+
}

0 commit comments

Comments
 (0)