- Replace 11 per-frequency build environments with 3 role-based targets (production, debug, test) using shared [env] base section - Move LoRa frequency and sender-ID config from build flags into config.h so all variants build from the same source - Add -fstack-protector-strong, -D_FORTIFY_SOURCE=2, -Wformat-security - Add Unity test framework to lib_deps for pio test support - Add __pycache__/ to .gitignore
150 lines
5.6 KiB
C++
150 lines
5.6 KiB
C++
#pragma once
|
||
|
||
#include <Arduino.h>
|
||
|
||
enum class DeviceRole : uint8_t {
|
||
Sender = 0,
|
||
Receiver = 1
|
||
};
|
||
|
||
enum class BatchRetryPolicy : uint8_t {
|
||
Keep = 0,
|
||
Drop = 1
|
||
};
|
||
|
||
// =============================================================================
|
||
// ██ DEPLOYMENT SETTINGS — adjust these for your hardware / frequency band
|
||
// =============================================================================
|
||
|
||
// LoRa frequency — uncomment ONE line:
|
||
#define LORA_FREQUENCY_HZ 433E6 // 433 MHz (EU ISM, default)
|
||
// #define LORA_FREQUENCY_HZ 868E6 // 868 MHz (EU SRD)
|
||
// #define LORA_FREQUENCY_HZ 915E6 // 915 MHz (US ISM)
|
||
|
||
// Expected sender device IDs (short-IDs). The receiver will only accept
|
||
// batches from these senders. Add one entry per physical sender board.
|
||
constexpr uint8_t NUM_SENDERS = 1;
|
||
inline constexpr uint16_t EXPECTED_SENDER_IDS[NUM_SENDERS] = {
|
||
0xF19C // TTGO #1 – 433 MHz sender
|
||
// 0x7EB4 // TTGO #2 – 868 MHz sender (uncomment & adjust NUM_SENDERS)
|
||
};
|
||
|
||
// =============================================================================
|
||
|
||
// Pin definitions
|
||
constexpr uint8_t PIN_LORA_SCK = 5;
|
||
constexpr uint8_t PIN_LORA_MISO = 19;
|
||
constexpr uint8_t PIN_LORA_MOSI = 27;
|
||
constexpr uint8_t PIN_LORA_NSS = 18;
|
||
constexpr uint8_t PIN_LORA_RST = 23;
|
||
constexpr uint8_t PIN_LORA_DIO0 = 26;
|
||
|
||
constexpr uint8_t PIN_OLED_SDA = 21;
|
||
constexpr uint8_t PIN_OLED_SCL = 22;
|
||
constexpr uint8_t PIN_OLED_RST = 16;
|
||
constexpr uint8_t OLED_I2C_ADDR = 0x3C;
|
||
constexpr uint8_t OLED_WIDTH = 128;
|
||
constexpr uint8_t OLED_HEIGHT = 64;
|
||
|
||
constexpr uint8_t PIN_BAT_ADC = 35;
|
||
|
||
constexpr uint8_t PIN_ROLE = 14;
|
||
constexpr uint8_t PIN_OLED_CTRL = 13;
|
||
|
||
constexpr uint8_t PIN_METER_RX = 34;
|
||
|
||
// LoRa radio parameters
|
||
constexpr long LORA_FREQUENCY = LORA_FREQUENCY_HZ;
|
||
constexpr uint8_t LORA_SPREADING_FACTOR = 12;
|
||
constexpr long LORA_BANDWIDTH = 125E3;
|
||
constexpr uint8_t LORA_CODING_RATE = 5;
|
||
constexpr uint8_t LORA_SYNC_WORD = 0x34;
|
||
constexpr uint8_t LORA_PREAMBLE_LEN = 8;
|
||
|
||
// Timing
|
||
constexpr uint32_t SENDER_WAKE_INTERVAL_SEC = 30;
|
||
constexpr uint32_t SYNC_REQUEST_INTERVAL_MS = 15000;
|
||
constexpr uint32_t OLED_PAGE_INTERVAL_MS = 4000;
|
||
constexpr uint32_t OLED_AUTO_OFF_MS = 10UL * 60UL * 1000UL;
|
||
constexpr uint32_t SENDER_OLED_READ_MS = 10000;
|
||
constexpr uint32_t METER_SAMPLE_INTERVAL_MS = 1000;
|
||
constexpr uint32_t METER_SEND_INTERVAL_MS = 30000;
|
||
constexpr uint32_t BATTERY_SAMPLE_INTERVAL_MS = 60000;
|
||
constexpr float BATTERY_CAL = 1.083f;
|
||
constexpr uint32_t BATCH_ACK_TIMEOUT_MS = 3000;
|
||
constexpr uint8_t ACK_REPEAT_COUNT = 3;
|
||
constexpr uint32_t ACK_REPEAT_DELAY_MS = 200;
|
||
constexpr uint8_t BATCH_MAX_RETRIES = 2;
|
||
constexpr uint8_t METER_BATCH_MAX_SAMPLES = 30;
|
||
constexpr uint8_t BATCH_QUEUE_DEPTH = 10;
|
||
constexpr BatchRetryPolicy BATCH_RETRY_POLICY = BatchRetryPolicy::Keep;
|
||
constexpr uint32_t WATCHDOG_TIMEOUT_SEC = 120;
|
||
constexpr uint32_t WIFI_RECONNECT_INTERVAL_MS = 60000; // WiFi reconnection retry interval (1 minute)
|
||
constexpr bool ENABLE_HA_DISCOVERY = true;
|
||
#ifndef SERIAL_DEBUG_MODE_FLAG
|
||
#define SERIAL_DEBUG_MODE_FLAG 0
|
||
#endif
|
||
constexpr bool SERIAL_DEBUG_MODE = SERIAL_DEBUG_MODE_FLAG != 0;
|
||
constexpr bool SERIAL_DEBUG_DUMP_JSON = false;
|
||
constexpr bool LORA_SEND_BYPASS = false;
|
||
|
||
// --- Power management (sender) ---
|
||
// Light-sleep between 1 Hz samples: saves ~25 mA vs active delay().
|
||
// UART HW FIFO is 128 bytes; at 9600 baud (~960 B/s) max safe chunk ≈133 ms.
|
||
#ifndef ENABLE_LIGHT_SLEEP_IDLE
|
||
#define ENABLE_LIGHT_SLEEP_IDLE 1
|
||
#endif
|
||
constexpr bool LIGHT_SLEEP_IDLE = ENABLE_LIGHT_SLEEP_IDLE != 0;
|
||
constexpr uint32_t LIGHT_SLEEP_CHUNK_MS = 100;
|
||
|
||
// CPU frequency for sender (MHz). 80 = default, 40 = aggressive savings.
|
||
#ifndef SENDER_CPU_MHZ
|
||
#define SENDER_CPU_MHZ 80
|
||
#endif
|
||
|
||
// Log-throttle interval for sender diagnostics (ms). Higher = less serial TX.
|
||
constexpr uint32_t SENDER_DIAG_LOG_INTERVAL_MS = SERIAL_DEBUG_MODE ? 5000 : 30000;
|
||
|
||
// Meter driver: max time (ms) to wait for a complete frame before discarding.
|
||
// Lower values recover faster from broken frames and save wasted polling.
|
||
constexpr uint32_t METER_FRAME_TIMEOUT_CFG_MS = 3000;
|
||
|
||
// Meter driver: backoff ceiling on consecutive frame failures (ms).
|
||
constexpr uint32_t METER_FAIL_BACKOFF_MAX_MS = 500;
|
||
constexpr uint32_t METER_FAIL_BACKOFF_BASE_MS = 10;
|
||
constexpr bool ENABLE_SD_LOGGING = true;
|
||
constexpr uint8_t PIN_SD_CS = 13;
|
||
constexpr uint8_t PIN_SD_MOSI = 15;
|
||
constexpr uint8_t PIN_SD_MISO = 2;
|
||
constexpr uint8_t PIN_SD_SCK = 14;
|
||
constexpr uint16_t SD_HISTORY_MAX_DAYS = 30;
|
||
constexpr uint16_t SD_HISTORY_MIN_RES_MIN = 1;
|
||
constexpr uint16_t SD_HISTORY_MAX_BINS = 4000;
|
||
constexpr uint16_t SD_HISTORY_TIME_BUDGET_MS = 10;
|
||
constexpr const char *TIMEZONE_TZ = "CET-1CEST,M3.5.0/2,M10.5.0/3";
|
||
constexpr const char *AP_SSID_PREFIX = "DD3-Bridge-";
|
||
constexpr const char *AP_PASSWORD = "changeme123";
|
||
constexpr bool WEB_AUTH_REQUIRE_STA = true;
|
||
constexpr bool WEB_AUTH_REQUIRE_AP = true;
|
||
// SECURITY: these defaults are only used until the user sets credentials via
|
||
// the web config page (/wifi). The first-boot AP forces password change.
|
||
constexpr const char *WEB_AUTH_DEFAULT_USER = "admin";
|
||
constexpr const char *WEB_AUTH_DEFAULT_PASS = "admin";
|
||
inline constexpr char HA_MANUFACTURER[] = "AcidBurns";
|
||
static_assert(
|
||
HA_MANUFACTURER[0] == 'A' &&
|
||
HA_MANUFACTURER[1] == 'c' &&
|
||
HA_MANUFACTURER[2] == 'i' &&
|
||
HA_MANUFACTURER[3] == 'd' &&
|
||
HA_MANUFACTURER[4] == 'B' &&
|
||
HA_MANUFACTURER[5] == 'u' &&
|
||
HA_MANUFACTURER[6] == 'r' &&
|
||
HA_MANUFACTURER[7] == 'n' &&
|
||
HA_MANUFACTURER[8] == 's' &&
|
||
HA_MANUFACTURER[9] == '\0',
|
||
"HA_MANUFACTURER must remain exactly \"AcidBurns\"");
|
||
|
||
constexpr uint32_t MIN_ACCEPTED_EPOCH_UTC = 1769904000UL; // 2026-02-01 00:00:00 UTC
|
||
|
||
DeviceRole detect_role();
|