From c65e5fcf23dda6e7a04345fa5fdc79c0d7e0403c Mon Sep 17 00:00:00 2001
From: Eric Duminil <eric.duminil@gmail.com>
Date: Sat, 17 Apr 2021 21:59:43 +0200
Subject: [PATCH] Some lambda examples

---
 ampel-firmware/csv_writer.cpp      |  9 +++++++++
 ampel-firmware/mqtt.cpp            | 10 +++++-----
 ampel-firmware/sensor_commands.cpp | 30 +++++++++++++++++++-----------
 3 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/ampel-firmware/csv_writer.cpp b/ampel-firmware/csv_writer.cpp
index db3b22e..d41d2b5 100644
--- a/ampel-firmware/csv_writer.cpp
+++ b/ampel-firmware/csv_writer.cpp
@@ -118,6 +118,15 @@ namespace csv_writer {
     Serial.println();
 
     sensor_commands::defineIntCallback("csv", setCSVinterval, " 60 (Sets CSV writing interval, in s)");
+    sensor_commands::defineIntCallback("double", [](int32_t x) {
+      Serial.print("2 * ");
+      Serial.print(x);
+      Serial.print(" = ");
+      Serial.println(2 * x);
+    }, " (Say Hello;)");
+    sensor_commands::defineCallback("hello", []() {
+      Serial.println("SAY HELLO");
+    }, " (Say Hello;)");
     sensor_commands::defineCallback("format_filesystem", formatFilesystem, " (Deletes the whole filesystem.)");
   }
 
diff --git a/ampel-firmware/mqtt.cpp b/ampel-firmware/mqtt.cpp
index 053b777..eacc8c5 100644
--- a/ampel-firmware/mqtt.cpp
+++ b/ampel-firmware/mqtt.cpp
@@ -37,6 +37,10 @@ namespace mqtt {
     mqttClient.setServer(config::mqtt_server, config::mqtt_port);
 
     sensor_commands::defineIntCallback("mqtt", setMQTTinterval, " 60 (Sets MQTT sending interval, in s)");
+    sensor_commands::defineCallback("publish", []() {
+      Serial.println(F("Forcing MQTT publish now."));
+      last_sent_at = -config::sending_interval;
+    }, " (Force publish now)");
   }
 
   void publish(const String &timestamp, int16_t co2, float temperature, float humidity) {
@@ -97,16 +101,12 @@ namespace mqtt {
 
     //TODO: Move this logic to a separate class, which could be used by Serial/MQTT/WebServer
 
-    if (messageString == "publish") {
-      Serial.println(F("Forcing MQTT publish now."));
-      last_sent_at = 0;
-    } else if (messageString == "night_mode") {
+    if (messageString == "night_mode") {
       led_effects::toggleNightMode();
     } else if (messageString == "local_ip") {
       sendInfoAboutLocalNetwork();
     } else if (messageString == "reset") {
       ESP.restart(); // softer than ESP.reset()
-    } else {
     }
   }
 
diff --git a/ampel-firmware/sensor_commands.cpp b/ampel-firmware/sensor_commands.cpp
index 4401b34..b29d5dc 100644
--- a/ampel-firmware/sensor_commands.cpp
+++ b/ampel-firmware/sensor_commands.cpp
@@ -13,16 +13,18 @@ namespace sensor_commands {
       void (*voidFunction)(void);
     };
     const char *doc;
+    bool has_parameter;
   };
 
   Callback callbacks[MAX_CALLBACKS];
 
-  //NOTE: Probably possible to DRY
+  //NOTE: Probably possible to DRY (with templates?)
   void defineCallback(const char *name, void (*function)(void), const char *doc) {
     if (callbacks_count < MAX_CALLBACKS) {
       callbacks[callbacks_count].name = name;
       callbacks[callbacks_count].voidFunction = function;
       callbacks[callbacks_count].doc = doc;
+      callbacks[callbacks_count].has_parameter = false;
       callbacks_count++;
     } else {
       Serial.println(F("Too many callbacks have been defined."));
@@ -34,13 +36,14 @@ namespace sensor_commands {
       callbacks[callbacks_count].name = name;
       callbacks[callbacks_count].intFunction = function;
       callbacks[callbacks_count].doc = doc;
+      callbacks[callbacks_count].has_parameter = true;
       callbacks_count++;
     } else {
       Serial.println(F("Too many callbacks have been defined."));
     }
   }
 
-  uint8_t parseCommand(const char *command, char *function_name, int32_t &parameter) {
+  uint8_t parseCommand(const char *command, char *function_name, int32_t &argument) {
     char split_command[MAX_COMMAND_SIZE];
     strlcpy(split_command, command, MAX_COMMAND_SIZE);
     Serial.print(F("Received : '"));
@@ -58,13 +61,13 @@ namespace sensor_commands {
     uint8_t code = 0;
     if (arg) {
       char *end;
-      parameter = strtol(arg, &end, 10);
+      argument = strtol(arg, &end, 10);
       if (*end) {
         // Second argument isn't a number
         code = 2;
       }
     } else {
-      // No parameter
+      // No argument
       code = 2;
     }
     return code;
@@ -82,17 +85,22 @@ namespace sensor_commands {
 
   void run(const char *command) {
     char function_name[MAX_COMMAND_SIZE];
-    int32_t parameter = 0;
-    parseCommand(command, function_name, parameter);
+    int32_t argument = 0;
+    bool has_argument;
+    has_argument = (parseCommand(command, function_name, argument) == 0);
 
     for (uint8_t i = 0; i < callbacks_count; i++) {
-      if (!strcmp(function_name, callbacks[i].name)) {
+      if (!strcmp(function_name, callbacks[i].name) && has_argument == callbacks[i].has_parameter) {
         Serial.print("Calling : ");
         Serial.print(function_name);
-        Serial.print("(");
-        Serial.print(parameter);
-        Serial.println(")");
-        callbacks[i].intFunction(parameter);
+        if (has_argument) {
+          Serial.print("(");
+          Serial.print(argument);
+          Serial.println(")");
+          callbacks[i].intFunction(argument);
+        } else {
+          callbacks[i].voidFunction();
+        }
         return;
       }
     }
-- 
GitLab