Commit 98010e91 authored by Eric Duminil's avatar Eric Duminil
Browse files

c strings everywhere.

parent 36bd5ec7
...@@ -87,6 +87,10 @@ void setup() { ...@@ -87,6 +87,10 @@ void setup() {
Serial.print(F("Board : ")); Serial.print(F("Board : "));
Serial.println(ampel.board); Serial.println(ampel.board);
#ifdef AMPEL_CSV
csv_writer::initialize(ampel.sensorId);
#endif
#ifdef AMPEL_WIFI #ifdef AMPEL_WIFI
WiFiConnect(ampel.sensorId); WiFiConnect(ampel.sensorId);
...@@ -100,7 +104,7 @@ void setup() { ...@@ -100,7 +104,7 @@ void setup() {
ntp::initialize(); ntp::initialize();
if (MDNS.begin(ampel.sensorId.c_str())) { // Start the mDNS responder for SENSOR_ID.local if (MDNS.begin(ampel.sensorId)) { // Start the mDNS responder for SENSOR_ID.local
MDNS.addService("http", "tcp", 80); MDNS.addService("http", "tcp", 80);
Serial.println(F("mDNS responder started")); Serial.println(F("mDNS responder started"));
} else { } else {
...@@ -108,15 +112,11 @@ void setup() { ...@@ -108,15 +112,11 @@ void setup() {
} }
# ifdef AMPEL_MQTT # ifdef AMPEL_MQTT
mqtt::initialize("CO2sensors/" + ampel.sensorId); mqtt::initialize(ampel.sensorId);
# endif # endif
} }
#endif #endif
#ifdef AMPEL_CSV
csv_writer::initialize();
#endif
#if defined(AMPEL_LORAWAN) && defined(ESP32) #if defined(AMPEL_LORAWAN) && defined(ESP32)
lorawan::initialize(); lorawan::initialize();
#endif #endif
......
...@@ -22,7 +22,7 @@ namespace sensor { ...@@ -22,7 +22,7 @@ namespace sensor {
extern uint16_t co2; extern uint16_t co2;
extern float temperature; extern float temperature;
extern float humidity; extern float humidity;
extern char timestamp[23]; extern char timestamp[];
void initialize(); void initialize();
bool processData(); bool processData();
......
...@@ -78,13 +78,15 @@ namespace csv_writer { ...@@ -78,13 +78,15 @@ namespace csv_writer {
} }
#endif #endif
const String filename = "/" + ampel.sensorId + ".csv"; char filename[15]; // "/ESPxxxxxx.csv\0"
int getAvailableSpace() { int getAvailableSpace() {
return getTotalSpace() - getUsedSpace(); return getTotalSpace() - getUsedSpace();
} }
void initialize() { void initialize(const char *sensorId) {
snprintf(filename, sizeof(filename), "/%s.csv", sensorId);
Serial.print(F("Initializing FS...")); Serial.print(F("Initializing FS..."));
if (mountFS()) { if (mountFS()) {
Serial.println(F("done.")); Serial.println(F("done."));
...@@ -187,7 +189,7 @@ namespace csv_writer { ...@@ -187,7 +189,7 @@ namespace csv_writer {
} }
csv_file.close(); csv_file.close();
} }
Serial.println(F("################")); Serial.println(F("######################"));
} }
void formatFilesystem() { void formatFilesystem() {
......
...@@ -20,11 +20,11 @@ namespace config { ...@@ -20,11 +20,11 @@ namespace config {
extern uint16_t csv_interval; // [s] extern uint16_t csv_interval; // [s]
} }
namespace csv_writer { namespace csv_writer {
extern char last_successful_write[23]; extern char last_successful_write[];
void initialize(); void initialize(const char *sensorId);
void logIfTimeHasCome(const char* timestamp, const int16_t &co2, const float &temperature, const float &humidity); void logIfTimeHasCome(const char *timestamp, const int16_t &co2, const float &temperature, const float &humidity);
int getAvailableSpace(); int getAvailableSpace();
extern const String filename; extern char filename[];
void setCSVinterval(int32_t csv_interval); void setCSVinterval(int32_t csv_interval);
void showCSVContent(); void showCSVContent();
......
...@@ -23,13 +23,13 @@ namespace mqtt { ...@@ -23,13 +23,13 @@ namespace mqtt {
unsigned long last_failed_at = 0; unsigned long last_failed_at = 0;
bool connected = false; bool connected = false;
String publish_topic; char publish_topic[21]; // e.g. "CO2sensors/ESPxxxxxx\0"
const char *json_sensor_format; const char *json_sensor_format;
char last_successful_publish[23] = ""; char last_successful_publish[23] = "";
void initialize(String &topic) { void initialize(const char *sensorId) {
json_sensor_format = PSTR("{\"time\":\"%s\", \"co2\":%d, \"temp\":%.1f, \"rh\":%.1f}"); json_sensor_format = PSTR("{\"time\":\"%s\", \"co2\":%d, \"temp\":%.1f, \"rh\":%.1f}");
publish_topic = topic; snprintf(publish_topic, sizeof(publish_topic), "CO2sensors/%s", sensorId);
#if defined(ESP8266) #if defined(ESP8266)
espClient.setInsecure(); // Sorry, we don't want to flash the sensors every 3 months. espClient.setInsecure(); // Sorry, we don't want to flash the sensors every 3 months.
#endif #endif
...@@ -49,7 +49,7 @@ namespace mqtt { ...@@ -49,7 +49,7 @@ namespace mqtt {
char payload[75]; // Should be enough for json... char payload[75]; // Should be enough for json...
snprintf(payload, sizeof(payload), json_sensor_format, timestamp, co2, temperature, humidity); snprintf(payload, sizeof(payload), json_sensor_format, timestamp, co2, temperature, humidity);
// Topic is the same as clientID. e.g. 'CO2sensors/ESP3d03da' // Topic is the same as clientID. e.g. 'CO2sensors/ESP3d03da'
if (mqttClient.publish(publish_topic.c_str(), payload)) { if (mqttClient.publish(publish_topic, payload)) {
Serial.println(F("OK")); Serial.println(F("OK"));
ntp::getLocalTime(last_successful_publish); ntp::getLocalTime(last_successful_publish);
} else { } else {
...@@ -96,7 +96,7 @@ namespace mqtt { ...@@ -96,7 +96,7 @@ namespace mqtt {
led_effects::onBoardLEDOn(); led_effects::onBoardLEDOn();
// Wait for connection, at most 15s (default) // Wait for connection, at most 15s (default)
mqttClient.connect(publish_topic.c_str(), config::mqtt_user, config::mqtt_password); mqttClient.connect(publish_topic, config::mqtt_user, config::mqtt_password);
led_effects::onBoardLEDOff(); led_effects::onBoardLEDOff();
connected = mqttClient.connected(); connected = mqttClient.connected();
...@@ -104,7 +104,7 @@ namespace mqtt { ...@@ -104,7 +104,7 @@ namespace mqtt {
if (connected) { if (connected) {
if (config::allow_mqtt_commands) { if (config::allow_mqtt_commands) {
char control_topic[60]; // Should be enough for "CO2sensors/ESPd03cc5/control" char control_topic[60]; // Should be enough for "CO2sensors/ESPd03cc5/control"
snprintf(control_topic, sizeof(control_topic), "%s/control", publish_topic.c_str()); snprintf(control_topic, sizeof(control_topic), "%s/control", publish_topic);
mqttClient.subscribe(control_topic); mqttClient.subscribe(control_topic);
mqttClient.setCallback(controlSensorCallback); mqttClient.setCallback(controlSensorCallback);
} }
...@@ -153,7 +153,7 @@ namespace mqtt { ...@@ -153,7 +153,7 @@ namespace mqtt {
// The sensor will send the info to "CO2sensors/ESP123456/info". // The sensor will send the info to "CO2sensors/ESP123456/info".
void sendInfoAboutLocalNetwork() { void sendInfoAboutLocalNetwork() {
char info_topic[60]; // Should be enough for "CO2sensors/ESP123456/info" char info_topic[60]; // Should be enough for "CO2sensors/ESP123456/info"
snprintf(info_topic, sizeof(info_topic), "%s/info", publish_topic.c_str()); snprintf(info_topic, sizeof(info_topic), "%s/info", publish_topic);
char payload[75]; // Should be enough for info json... char payload[75]; // Should be enough for info json...
const char *json_info_format = PSTR("{\"local_ip\":\"%s\", \"ssid\":\"%s\"}"); const char *json_info_format = PSTR("{\"local_ip\":\"%s\", \"ssid\":\"%s\"}");
......
...@@ -13,7 +13,7 @@ namespace config { ...@@ -13,7 +13,7 @@ namespace config {
namespace mqtt { namespace mqtt {
extern char last_successful_publish[]; extern char last_successful_publish[];
extern bool connected; extern bool connected;
void initialize(String &topic); void initialize(const char *sensorId);
void keepConnection(); void keepConnection();
void publishIfTimeHasCome(const char *timestamp, const int16_t &co2, const float &temp, const float &hum); void publishIfTimeHasCome(const char *timestamp, const int16_t &co2, const float &temp, const float &hum);
......
...@@ -13,20 +13,6 @@ const char *current_board = "ESP32"; ...@@ -13,20 +13,6 @@ const char *current_board = "ESP32";
const char *current_board = "UNKNOWN"; const char *current_board = "UNKNOWN";
#endif #endif
// Get last 3 bytes of ESP MAC (worldwide unique)
String macToID() {
uint8_t mac[6];
WiFi.macAddress(mac);
String result;
for (int i = 3; i < 6; i++) {
if (mac[i] < 16)
result += '0';
result += String(mac[i], HEX);
}
result.toLowerCase();
return result;
}
//NOTE: ESP32 sometimes couldn't access the NTP server, and every loop would take +1000ms //NOTE: ESP32 sometimes couldn't access the NTP server, and every loop would take +1000ms
// ifdefs could be used to define functions specific to ESP32, e.g. with configTime // ifdefs could be used to define functions specific to ESP32, e.g. with configTime
namespace ntp { namespace ntp {
...@@ -70,8 +56,18 @@ void Ampel::showFreeSpace() { ...@@ -70,8 +56,18 @@ void Ampel::showFreeSpace() {
Serial.println(F(" bytes.")); Serial.println(F(" bytes."));
} }
char sensorId[10]; // e.g "ESPxxxxxx\0"
char* getSensorId() {
uint8_t mac[6];
WiFi.macAddress(mac);
// Get last 3 bytes of ESP MAC (worldwide unique)
snprintf(sensorId, sizeof(sensorId), "ESP%02x%02x%02x", mac[3], mac[4], mac[5]);
return sensorId;
}
Ampel::Ampel() : Ampel::Ampel() :
board(current_board), sensorId("ESP" + macToID()), max_loop_duration(0) { board(current_board), sensorId(getSensorId()), max_loop_duration(0) {
sensor_console::defineIntCommand("set_time", ntp::setLocalTime, F(" 1618829570 (Sets time to the given UNIX time)")); sensor_console::defineIntCommand("set_time", ntp::setLocalTime, F(" 1618829570 (Sets time to the given UNIX time)"));
sensor_console::defineCommand("free", Ampel::showFreeSpace, F(" (Displays available heap space)")); sensor_console::defineCommand("free", Ampel::showFreeSpace, F(" (Displays available heap space)"));
sensor_console::defineCommand("reset", []() { sensor_console::defineCommand("reset", []() {
......
...@@ -37,7 +37,7 @@ private: ...@@ -37,7 +37,7 @@ private:
static void showFreeSpace(); static void showFreeSpace();
public: public:
const char *board; const char *board;
const String sensorId; const char *sensorId;
uint32_t max_loop_duration; uint32_t max_loop_duration;
Ampel(); Ampel();
}; };
......
...@@ -65,7 +65,7 @@ namespace web_server { ...@@ -65,7 +65,7 @@ namespace web_server {
#ifdef AMPEL_CSV #ifdef AMPEL_CSV
"<li class='pure-menu-item'><a href='#graph' class='pure-menu-link'>Graph</a></li>\n" "<li class='pure-menu-item'><a href='#graph' class='pure-menu-link'>Graph</a></li>\n"
"<li class='pure-menu-item'><a href='#log' class='pure-menu-link'>Log</a></li>\n" "<li class='pure-menu-item'><a href='#log' class='pure-menu-link'>Log</a></li>\n"
"<li class='pure-menu-item'><a href='./%s' class='pure-menu-link'>Download CSV</a></li>\n" "<li class='pure-menu-item'><a href='%s' class='pure-menu-link'>Download CSV</a></li>\n"
#endif #endif
"<li class='pure-menu-item' id='led'>&#11044;</li>\n" // LED "<li class='pure-menu-item' id='led'>&#11044;</li>\n" // LED
"</ul></div></div>\n" "</ul></div></div>\n"
...@@ -132,7 +132,7 @@ namespace web_server { ...@@ -132,7 +132,7 @@ namespace web_server {
#ifdef AMPEL_CSV #ifdef AMPEL_CSV
"<script>\n" "<script>\n"
"document.body.style.cursor = 'default';\n" "document.body.style.cursor = 'default';\n"
"fetch('./%s',{credentials:'include'})\n" "fetch('%s',{credentials:'include'})\n"
".then(response=>response.text())\n" ".then(response=>response.text())\n"
".then(csvText=>csvToTable(csvText))\n" ".then(csvText=>csvToTable(csvText))\n"
".then(htmlTable=>addLogTableToPage(htmlTable))\n" ".then(htmlTable=>addLogTableToPage(htmlTable))\n"
...@@ -177,7 +177,7 @@ namespace web_server { ...@@ -177,7 +177,7 @@ namespace web_server {
http.on("/", handleWebServerRoot); http.on("/", handleWebServerRoot);
http.on("/command", handleWebServerCommand); http.on("/command", handleWebServerCommand);
#ifdef AMPEL_CSV #ifdef AMPEL_CSV
http.on("/" + csv_writer::filename, handleWebServerCSV); http.on(csv_writer::filename, handleWebServerCSV); //NOTE: csv_writer should have been initialized first.
http.on("/delete_csv", HTTP_POST, handleDeleteCSV); http.on("/delete_csv", HTTP_POST, handleDeleteCSV);
#endif #endif
http.onNotFound(handlePageNotFound); http.onNotFound(handlePageNotFound);
...@@ -212,10 +212,9 @@ namespace web_server { ...@@ -212,10 +212,9 @@ namespace web_server {
char content[2000]; // Update if needed char content[2000]; // Update if needed
// INFO - Header size : 1767 - Body size : 1812 - Script size : 1909 // INFO - Header size : 1767 - Body size : 1812 - Script size : 1909
snprintf_P(content, sizeof(content), header_template, sensor::co2, ampel.sensorId.c_str(), snprintf_P(content, sizeof(content), header_template, sensor::co2, ampel.sensorId, WiFi.localIP().toString().c_str()
WiFi.localIP().toString().c_str()
#ifdef AMPEL_CSV #ifdef AMPEL_CSV
, csv_writer::filename.c_str() , csv_writer::filename
#endif #endif
); );
...@@ -225,7 +224,7 @@ namespace web_server { ...@@ -225,7 +224,7 @@ namespace web_server {
http.send_P(200, PSTR("text/html"), content); http.send_P(200, PSTR("text/html"), content);
// Body // Body
snprintf_P(content, sizeof(content), body_template, ampel.sensorId.c_str(), sensor::co2, sensor::temperature, snprintf_P(content, sizeof(content), body_template, ampel.sensorId, sensor::co2, sensor::temperature,
sensor::humidity, sensor::timestamp, config::measurement_timestep, sensor::humidity, sensor::timestamp, config::measurement_timestep,
#ifdef AMPEL_CSV #ifdef AMPEL_CSV
csv_writer::last_successful_write, config::csv_interval, csv_writer::getAvailableSpace() / 1024, csv_writer::last_successful_write, config::csv_interval, csv_writer::getAvailableSpace() / 1024,
...@@ -237,9 +236,9 @@ namespace web_server { ...@@ -237,9 +236,9 @@ namespace web_server {
lorawan::connected ? "Yes" : "No", LMIC_FREQUENCY_PLAN, lorawan::last_transmission, lorawan::connected ? "Yes" : "No", LMIC_FREQUENCY_PLAN, lorawan::last_transmission,
config::lorawan_sending_interval, config::lorawan_sending_interval,
#endif #endif
config::temperature_offset, config::auto_calibrate_sensor ? "Yes" : "No", ampel.sensorId.c_str(), config::temperature_offset, config::auto_calibrate_sensor ? "Yes" : "No", ampel.sensorId, ampel.sensorId,
ampel.sensorId.c_str(), WiFi.localIP().toString().c_str(), WiFi.localIP().toString().c_str(), WiFi.localIP().toString().c_str(), WiFi.localIP().toString().c_str(), get_free_heap_size(),
get_free_heap_size(), ampel.max_loop_duration, ampel.board, dd, hh, mm, ss); ampel.max_loop_duration, ampel.board, dd, hh, mm, ss);
Serial.print(F(" - Body size : ")); Serial.print(F(" - Body size : "));
http.sendContent(content); http.sendContent(content);
...@@ -248,7 +247,7 @@ namespace web_server { ...@@ -248,7 +247,7 @@ namespace web_server {
// Script // Script
snprintf_P(content, sizeof(content), script_template snprintf_P(content, sizeof(content), script_template
#ifdef AMPEL_CSV #ifdef AMPEL_CSV
, csv_writer::filename.c_str(), ampel.sensorId.c_str() , csv_writer::filename, ampel.sensorId
#endif #endif
); );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment