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

c strings everywhere.

parent 36bd5ec7
......@@ -87,6 +87,10 @@ void setup() {
Serial.print(F("Board : "));
Serial.println(ampel.board);
#ifdef AMPEL_CSV
csv_writer::initialize(ampel.sensorId);
#endif
#ifdef AMPEL_WIFI
WiFiConnect(ampel.sensorId);
......@@ -100,7 +104,7 @@ void setup() {
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);
Serial.println(F("mDNS responder started"));
} else {
......@@ -108,15 +112,11 @@ void setup() {
}
# ifdef AMPEL_MQTT
mqtt::initialize("CO2sensors/" + ampel.sensorId);
mqtt::initialize(ampel.sensorId);
# endif
}
#endif
#ifdef AMPEL_CSV
csv_writer::initialize();
#endif
#if defined(AMPEL_LORAWAN) && defined(ESP32)
lorawan::initialize();
#endif
......
......@@ -22,7 +22,7 @@ namespace sensor {
extern uint16_t co2;
extern float temperature;
extern float humidity;
extern char timestamp[23];
extern char timestamp[];
void initialize();
bool processData();
......
......@@ -78,13 +78,15 @@ namespace csv_writer {
}
#endif
const String filename = "/" + ampel.sensorId + ".csv";
char filename[15]; // "/ESPxxxxxx.csv\0"
int getAvailableSpace() {
return getTotalSpace() - getUsedSpace();
}
void initialize() {
void initialize(const char *sensorId) {
snprintf(filename, sizeof(filename), "/%s.csv", sensorId);
Serial.print(F("Initializing FS..."));
if (mountFS()) {
Serial.println(F("done."));
......@@ -187,7 +189,7 @@ namespace csv_writer {
}
csv_file.close();
}
Serial.println(F("################"));
Serial.println(F("######################"));
}
void formatFilesystem() {
......
......@@ -20,11 +20,11 @@ namespace config {
extern uint16_t csv_interval; // [s]
}
namespace csv_writer {
extern char last_successful_write[23];
void initialize();
void logIfTimeHasCome(const char* timestamp, const int16_t &co2, const float &temperature, const float &humidity);
extern char last_successful_write[];
void initialize(const char *sensorId);
void logIfTimeHasCome(const char *timestamp, const int16_t &co2, const float &temperature, const float &humidity);
int getAvailableSpace();
extern const String filename;
extern char filename[];
void setCSVinterval(int32_t csv_interval);
void showCSVContent();
......
......@@ -23,13 +23,13 @@ namespace mqtt {
unsigned long last_failed_at = 0;
bool connected = false;
String publish_topic;
char publish_topic[21]; // e.g. "CO2sensors/ESPxxxxxx\0"
const char *json_sensor_format;
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}");
publish_topic = topic;
snprintf(publish_topic, sizeof(publish_topic), "CO2sensors/%s", sensorId);
#if defined(ESP8266)
espClient.setInsecure(); // Sorry, we don't want to flash the sensors every 3 months.
#endif
......@@ -49,7 +49,7 @@ namespace mqtt {
char payload[75]; // Should be enough for json...
snprintf(payload, sizeof(payload), json_sensor_format, timestamp, co2, temperature, humidity);
// 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"));
ntp::getLocalTime(last_successful_publish);
} else {
......@@ -96,7 +96,7 @@ namespace mqtt {
led_effects::onBoardLEDOn();
// 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();
connected = mqttClient.connected();
......@@ -104,7 +104,7 @@ namespace mqtt {
if (connected) {
if (config::allow_mqtt_commands) {
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.setCallback(controlSensorCallback);
}
......@@ -153,7 +153,7 @@ namespace mqtt {
// The sensor will send the info to "CO2sensors/ESP123456/info".
void sendInfoAboutLocalNetwork() {
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...
const char *json_info_format = PSTR("{\"local_ip\":\"%s\", \"ssid\":\"%s\"}");
......
......@@ -13,7 +13,7 @@ namespace config {
namespace mqtt {
extern char last_successful_publish[];
extern bool connected;
void initialize(String &topic);
void initialize(const char *sensorId);
void keepConnection();
void publishIfTimeHasCome(const char *timestamp, const int16_t &co2, const float &temp, const float &hum);
......
......@@ -13,20 +13,6 @@ const char *current_board = "ESP32";
const char *current_board = "UNKNOWN";
#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
// ifdefs could be used to define functions specific to ESP32, e.g. with configTime
namespace ntp {
......@@ -70,8 +56,18 @@ void Ampel::showFreeSpace() {
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() :
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::defineCommand("free", Ampel::showFreeSpace, F(" (Displays available heap space)"));
sensor_console::defineCommand("reset", []() {
......
......@@ -37,7 +37,7 @@ private:
static void showFreeSpace();
public:
const char *board;
const String sensorId;
const char *sensorId;
uint32_t max_loop_duration;
Ampel();
};
......
......@@ -65,7 +65,7 @@ namespace web_server {
#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='#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
"<li class='pure-menu-item' id='led'>&#11044;</li>\n" // LED
"</ul></div></div>\n"
......@@ -132,7 +132,7 @@ namespace web_server {
#ifdef AMPEL_CSV
"<script>\n"
"document.body.style.cursor = 'default';\n"
"fetch('./%s',{credentials:'include'})\n"
"fetch('%s',{credentials:'include'})\n"
".then(response=>response.text())\n"
".then(csvText=>csvToTable(csvText))\n"
".then(htmlTable=>addLogTableToPage(htmlTable))\n"
......@@ -177,7 +177,7 @@ namespace web_server {
http.on("/", handleWebServerRoot);
http.on("/command", handleWebServerCommand);
#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);
#endif
http.onNotFound(handlePageNotFound);
......@@ -212,10 +212,9 @@ namespace web_server {
char content[2000]; // Update if needed
// INFO - Header size : 1767 - Body size : 1812 - Script size : 1909
snprintf_P(content, sizeof(content), header_template, sensor::co2, ampel.sensorId.c_str(),
WiFi.localIP().toString().c_str()
snprintf_P(content, sizeof(content), header_template, sensor::co2, ampel.sensorId, WiFi.localIP().toString().c_str()
#ifdef AMPEL_CSV
, csv_writer::filename.c_str()
, csv_writer::filename
#endif
);
......@@ -225,7 +224,7 @@ namespace web_server {
http.send_P(200, PSTR("text/html"), content);
// 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,
#ifdef AMPEL_CSV
csv_writer::last_successful_write, config::csv_interval, csv_writer::getAvailableSpace() / 1024,
......@@ -237,9 +236,9 @@ namespace web_server {
lorawan::connected ? "Yes" : "No", LMIC_FREQUENCY_PLAN, lorawan::last_transmission,
config::lorawan_sending_interval,
#endif
config::temperature_offset, config::auto_calibrate_sensor ? "Yes" : "No", ampel.sensorId.c_str(),
ampel.sensorId.c_str(), WiFi.localIP().toString().c_str(), WiFi.localIP().toString().c_str(),
get_free_heap_size(), ampel.max_loop_duration, ampel.board, dd, hh, mm, ss);
config::temperature_offset, config::auto_calibrate_sensor ? "Yes" : "No", ampel.sensorId, ampel.sensorId,
WiFi.localIP().toString().c_str(), WiFi.localIP().toString().c_str(), get_free_heap_size(),
ampel.max_loop_duration, ampel.board, dd, hh, mm, ss);
Serial.print(F(" - Body size : "));
http.sendContent(content);
......@@ -248,7 +247,7 @@ namespace web_server {
// Script
snprintf_P(content, sizeof(content), script_template
#ifdef AMPEL_CSV
, csv_writer::filename.c_str(), ampel.sensorId.c_str()
, csv_writer::filename, ampel.sensorId
#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