Skip to content

Commit

Permalink
Rewritten all configuration logic to use EEPROM
Browse files Browse the repository at this point in the history
MachineID, MQTT server and MQTT Shelly topic now configurable via WiFiManager
All persisted settings are now in SavedConfig and EEPROM
FabServer and Machine class now can be configured at runtime (not initialization time) with configure methods
Removed most of the secrets contents (only RFID tags remain)
  • Loading branch information
PBrunot committed Dec 27, 2023
1 parent 0ccea1d commit 74aced8
Show file tree
Hide file tree
Showing 13 changed files with 422 additions and 120 deletions.
1 change: 1 addition & 0 deletions include/BoardLogic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace fablabbg
bool authorize(const card::uid_t uid);
void changeStatus(Status newStatus);
bool board_init();
bool loadConfig();
void updateLCD() const;
void beep_ok() const;
void beep_failed() const;
Expand Down
30 changes: 18 additions & 12 deletions include/FabServer.hpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
#ifndef FABSERVER_H_
#define FABSERVER_H_

#include "FabUser.hpp"
#include "WiFi.h"
#include <array>
#include "conf.hpp"
#include <string>
#include <MQTTClient.h>
#include <chrono>
#include <functional>
#include <string>

#include <ArduinoJson.h>
#include "WiFi.h"
#include <MQTTClient.h>

#include "FabUser.hpp"
#include "conf.hpp"
#include "MQTTtypes.hpp"
#include <chrono>
#include "SavedConfig.hpp"

namespace fablabbg
{
Expand All @@ -19,9 +22,12 @@ namespace fablabbg
class FabServer
{
private:
const std::string_view wifi_ssid;
const std::string_view wifi_password;
const std::string_view server_ip;
std::string wifi_ssid;
std::string wifi_password;
std::string server_ip;
std::string mqtt_user;
std::string mqtt_password;
std::string mqtt_client_name;

MQTTClientCallbackSimpleFunction callback;
WiFiClass WiFiConnection;
Expand All @@ -36,7 +42,7 @@ namespace fablabbg

bool online = false;
bool answer_pending = false;
const uint8_t channel = -1;
uint8_t channel = -1;

void messageReceived(String &topic, String &payload);
bool publish(const Query &payload);
Expand All @@ -49,8 +55,7 @@ namespace fablabbg
static constexpr unsigned int MAX_MQTT_LENGTH = 128;

public:
FabServer() = delete;
FabServer(std::string_view ssid, std::string_view password, std::string_view server_ip, uint8_t channel = -1);
FabServer();
~FabServer() = default;

[[nodiscard]] std::unique_ptr<UserResponse> checkCard(const card::uid_t uid);
Expand All @@ -65,6 +70,7 @@ namespace fablabbg
bool connect();
bool connectWiFi() noexcept;
bool loop();
void configure(const SavedConfig &config); // Must be called before using the server

// Rule of 5 https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-five
FabServer(const FabServer &) = delete; // copy constructor
Expand Down
8 changes: 5 additions & 3 deletions include/Machine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ namespace fablabbg
UNKNOWN
};

Machine(MachineConfig config, FabServer &server);
Machine();
~Machine() = default;

bool maintenanceNeeded; // If true, machine needs maintenance
bool allowed; // If false, nobody can use the machine

FabUser &getActiveUser();
void configure(MachineConfig new_config, FabServer &serv); // Must be called before using the machine
MachineID getMachineId() const;
std::string getMachineName() const;
seconds getUsageDuration() const;
Expand All @@ -47,8 +48,9 @@ namespace fablabbg
bool isAutologoffExpired() const;

private:
MachineConfig config;
FabServer &server;
std::optional<MachineConfig> config;
std::optional<std::reference_wrapper<FabServer>> server;

bool active;
FabUser current_user;

Expand Down
32 changes: 17 additions & 15 deletions include/MachineConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

#include <cstdint>
#include <string>
#include <chrono>
#include "pins.hpp"
#include "conf.hpp"

using namespace std::chrono;

namespace fablabbg
{
Expand All @@ -20,33 +22,33 @@ namespace fablabbg

struct MachineID
{
const uint16_t id;
uint16_t id;
};
struct MachineConfig
{
const MachineID machine_id{0};
const MachineType machine_type{MachineType::INVALID};
const std::string machine_name;
MachineID machine_id{0};
MachineType machine_type{MachineType::INVALID};
std::string machine_name;
struct RelayConfig
{
const uint8_t pin{NO_PIN};
const bool active_low{false};
uint8_t pin{NO_PIN};
bool active_low{false};
} relay_config;
struct MQTTConfig
{
const std::string topic{""};
const std::string on_message{"on"};
const std::string off_message{"off"};
std::string topic{""};
std::string on_message{"on"};
std::string off_message{"off"};
} mqtt_config;

std::chrono::minutes autologoff{conf::machine::DEFAULT_AUTO_LOGOFF_DELAY};
minutes autologoff;

MachineConfig(MachineID id, MachineType type, std::string_view name,
uint8_t pin, bool act_low, std::string_view topic,
std::chrono::minutes autologoff) : machine_id(id), machine_type(type), machine_name(name),
relay_config{pin, act_low},
mqtt_config{std::string{topic}},
autologoff(autologoff) {}
minutes autologoff) : machine_id(id), machine_type(type), machine_name(name),
relay_config{pin, act_low},
mqtt_config{std::string{topic}},
autologoff(autologoff) {}
std::string toString() const;
bool hasRelay() const;
bool hasMqttSwitch() const;
Expand Down
45 changes: 45 additions & 0 deletions include/SavedConfig.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef SAVED_CONFIG_H_
#define SAVED_CONFIG_H_

#include <string>
#include <cstdint>
#include <optional>

#include "MachineConfig.hpp"
#include <EEPROM.h>

namespace fablabbg
{

struct SavedConfig
{
static constexpr auto FIELD_LENGTH = 40;
static constexpr auto INT_LENGTH = 5; // Must save as string for WiFiManager
static constexpr auto MAGIC_NUMBER = 0x44; // Increment when changing the struct

// Wifi
char ssid[FIELD_LENGTH]{0};
char password[FIELD_LENGTH]{0};

// MQTT
char mqtt_server[FIELD_LENGTH]{0};
char mqtt_user[FIELD_LENGTH]{0};
char mqtt_password[FIELD_LENGTH]{0};

// MQTT Switch
char machine_topic[FIELD_LENGTH]{0};

char machine_id[INT_LENGTH]{0};

// Magic number to check if the EEPROM is initialized
mutable uint8_t magic_number;

bool SaveToEEPROM() const;
std::string toString() const;

static std::optional<SavedConfig> LoadFromEEPROM();
static SavedConfig DefaultConfig();
};

} // namespace fablabbg
#endif // SAVED_CONFIG_H_
15 changes: 15 additions & 0 deletions include/conf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,25 @@
#include <string>
#include <chrono>

#include "MachineConfig.hpp"

using namespace std::chrono_literals;
using namespace std::chrono;

namespace fablabbg
{
namespace conf::default_config
{
static constexpr std::string_view ssid = "Wokwi-GUEST"; /* Default SSID */
static constexpr std::string_view password = ""; /* Default password */
static constexpr std::string_view mqtt_server = "127.0.0.1";
static constexpr std::string_view mqtt_user = "user";
static constexpr std::string_view mqtt_password = "password";
static constexpr std::string_view machine_topic = "shelly/command/switch:0";
static constexpr MachineID machine_id{1};
static constexpr std::string_view machine_name = "MACHINE1";
static constexpr MachineType machine_type = MachineType::LASER;
}
namespace conf::whitelist
{
static constexpr uint8_t LEN = 10U; /* Maximum number of whitelisted cards */
Expand Down Expand Up @@ -38,6 +52,7 @@ namespace fablabbg
static constexpr bool ENABLE_LOGS = true; /* True to add logs */
static constexpr bool ENABLE_TASK_LOGS = false; /* True to add logs regarding tasks scheduling and statistics */
static constexpr unsigned long SERIAL_SPEED_BDS = 115200; /* Serial speed in bauds */
static constexpr bool FORCE_PORTAL_RESET = false; /* True to force EEPROM reset */
}
namespace conf::buzzer
{
Expand Down
15 changes: 4 additions & 11 deletions include/globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,22 @@
#include "BoardLogic.hpp"
#include "Tasks.hpp"
#include "MockMQTTBroker.hpp"
#include "SavedConfig.hpp"

namespace fablabbg::Board
{
// Global variables
#if (WOKWI_SIMULATION)
MockRFIDWrapper rfid;
FabServer server("Wokwi-GUEST", "", "127.0.0.1", 6);
FabServer server;
MockMQTTBroker broker;
#else
RFIDWrapper rfid;
FabServer server(secrets::wifi::ssid, secrets::wifi::password, secrets::mqtt::server);
FabServer server;
#endif

LCDWrapper<conf::lcd::COLS, conf::lcd::ROWS> lcd(pins.lcd);

MachineConfig config1(secrets::machine::machine_id,
secrets::machine::machine_type,
secrets::machine::machine_name,
pins.relay.ch1_pin, false,
secrets::machine::machine_topic,
conf::machine::DEFAULT_AUTO_LOGOFF_DELAY);

Machine machine(config1, server);
Machine machine;
AuthProvider auth(secrets::cards::whitelist);
BoardLogic logic;
Tasks::Scheduler scheduler;
Expand Down
26 changes: 0 additions & 26 deletions include/secrets.hpp.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,4 @@ namespace fablabbg::secrets::cards
std::make_tuple(0xAABBCCDA, FabUser::UserLevel::FABLAB_USER, "USER1")};
} // namespace fablabbg::secrets::cards

namespace fablabbg::secrets::machine
{
// Machine connected to the ESP32
static constexpr std::string_view machine_name = "MACHINE1";
static constexpr MachineType machine_type = MachineType::LASER;
static constexpr std::string_view machine_topic = "shelly/command/switch:0";
static constexpr MachineID machine_id{1}; /* ID of the machine. Will be used to compose MQTT topic*/

} // namespace fablabbg::secrets::machine

namespace fablabbg::secrets::wifi
{
static constexpr std::string_view ssid = "aa"; /* Change with WIFI SSID name */
static constexpr std::string_view password = "bb"; /* Change with WIFI SSID password */
} // namespace fablabbg::secrets::wifi

namespace fablabbg::secrets::mqtt
{
static constexpr std::string_view client = "BOARD"; /* Name of with MQTT client */
static constexpr std::string_view user = "user"; /* Change with MQTT user */
static constexpr std::string_view password = "password"; /* Change with MQTT password */
static constexpr std::string_view server = "192.168.1.1"; /* IP of MQTT broker*/
static constexpr std::string_view topic = "/machine"; /* Initial part of the topic, machine ID will be added */
static constexpr std::string_view response_topic = "/reply"; /* Server reply (sub-topic of the full machine topic) */
} // namespace fablabbg::secrets::mqtt

#endif // SECRETS_H_
46 changes: 40 additions & 6 deletions src/BoardLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "AuthProvider.hpp"
#include "LCDWrapper.hpp"
#include "pins.hpp"
#include "SavedConfig.hpp"

namespace fablabbg
{
Expand Down Expand Up @@ -84,7 +85,7 @@ namespace fablabbg
{
if (conf::debug::ENABLE_LOGS)
Serial.printf("The configured machine ID %u is valid, maintenance=%d, allowed=%d\r\n",
secrets::machine::machine_id.id, result->needs_maintenance, result->allowed);
Board::machine.getMachineId().id, result->needs_maintenance, result->allowed);

Board::machine.maintenanceNeeded = result->needs_maintenance;
Board::machine.allowed = result->allowed;
Expand All @@ -93,7 +94,7 @@ namespace fablabbg
else
{
Serial.printf("The configured machine ID %u is unknown to the server\r\n",
secrets::machine::machine_id.id);
Board::machine.getMachineId().id);
}
}
}
Expand Down Expand Up @@ -289,12 +290,45 @@ namespace fablabbg
success &= (ledcSetup(conf::buzzer::LEDC_PWM_CHANNEL, conf::buzzer::BEEP_HZ, 10U) != 0);
ledcAttachPin(pins.buzzer.pin, conf::buzzer::LEDC_PWM_CHANNEL);

// Force Wifi disconnect as ESP32 has persistent wifi config
WiFi.disconnect();
success &= WiFi.mode(WIFI_STA);

if (conf::debug::ENABLE_LOGS)
{
Serial.printf("Board init complete, success = %d\r\n", success);
}

return success;
}

bool BoardLogic::loadConfig()
{
auto success = true;

// Load configuration
auto config = SavedConfig::LoadFromEEPROM();
if (!config)
{
Serial.printf("Configuration file not found, creating defaults...\r\n");
auto new_config = SavedConfig::DefaultConfig();
success &= new_config.SaveToEEPROM();
config = new_config;
}

if (conf::debug::ENABLE_LOGS)
{
Serial.println("Configuration from EEPROM:");
Serial.println(config->toString().c_str());
}

Board::server.configure(config.value());

MachineID mid{(uint16_t)atoi(config.value().machine_id)};
MachineConfig machine_conf(mid,
conf::default_config::machine_type,
conf::default_config::machine_name,
pins.relay.ch1_pin, false,
config.value().machine_topic,
conf::machine::DEFAULT_AUTO_LOGOFF_DELAY);

Board::machine.configure(machine_conf, Board::server);

return success;
}
Expand Down
Loading

0 comments on commit 74aced8

Please sign in to comment.