diff --git a/TankAlarm-092025-Client-Hologram/INSTALLATION.md b/TankAlarm-092025-Client-Hologram/INSTALLATION.md index 0952760..64a34f5 100644 --- a/TankAlarm-092025-Client-Hologram/INSTALLATION.md +++ b/TankAlarm-092025-Client-Hologram/INSTALLATION.md @@ -74,10 +74,41 @@ File: TankAlarm092025-Test.ino ## Software Configuration -### Step 1: Configure the Code +### Step 1: Configure SD Card (REQUIRED) +1. **Create SD Card Configuration**: + - Copy `tank_config_example.txt` to SD card as `tank_config.txt` + - Edit `tank_config.txt` with your specific settings + +2. **Critical Settings (REQUIRED)**: + ``` + # Update these values for your setup - ALL SETTINGS REQUIRED + SITE_NAME=Your Tank Farm Name + TANK_NUMBER=1 + HOLOGRAM_DEVICE_KEY=your_actual_device_key_here + ALARM_PHONE_PRIMARY=+15551234567 + ALARM_PHONE_SECONDARY=+15559876543 + DAILY_REPORT_PHONE=+15555551234 + ``` + +3. **Tank Physical Configuration**: + ``` + TANK_HEIGHT_INCHES=120 + HIGH_ALARM_INCHES=100 + LOW_ALARM_INCHES=12 + ``` + +4. **Insert SD Card**: Place configured SD card in device before powering on + +**IMPORTANT**: The device will not start without a properly configured `tank_config.txt` file on the SD card. The device will halt with error messages if: +- SD card is not inserted +- `tank_config.txt` file is missing +- HOLOGRAM_DEVICE_KEY is not set +- ALARM_PHONE_PRIMARY is not set + +### Step 2: Hardware Configuration (config.h) 1. **Copy Configuration Template**: - - Copy `config_template.h` to `config.h` - - Edit `config.h` with your specific settings + - Copy `config_template.h` to `config.h` (only if missing) + - This file now only contains hardware-specific constants 2. **Select Tank Level Sensor Type**: ```cpp @@ -85,17 +116,6 @@ File: TankAlarm092025-Test.ino #define SENSOR_TYPE DIGITAL_FLOAT ``` -3. **Update Configuration Values**: - ```cpp - // Replace with your actual Hologram.io device key - #define HOLOGRAM_DEVICE_KEY "your_device_key_here" - - // Update with your phone numbers (include country code) - #define ALARM_PHONE_PRIMARY "+12223334444" - #define ALARM_PHONE_SECONDARY "+15556667777" - #define DAILY_REPORT_PHONE "+18889990000" - ``` - 4. **Configure Sensor-Specific Settings**: **For Digital Float Switch (SENSOR_TYPE = DIGITAL_FLOAT)**: @@ -146,8 +166,8 @@ File: TankAlarm092025-Test.ino #define DAILY_REPORT_HOURS 24 ``` -### Step 2: Update Main Code -1. In `TankAlarm092025-Hologram.ino`, change this line: +### Step 3: Update Main Code +1. In `TankAlarm-092025-Client-Hologram.ino`, change this line: ```cpp // Change from: #include "config_template.h" @@ -155,7 +175,7 @@ File: TankAlarm092025-Test.ino #include "config.h" ``` -### Step 3: Upload Code +### Step 4: Upload Code 1. Connect MKR NB 1500 to computer via USB 2. Select correct board: Tools → Board → Arduino MKR NB 1500 3. Select correct port: Tools → Port → (your port) @@ -260,10 +280,14 @@ File: TankAlarm092025-Test.ino - **Annually**: Clean enclosure, inspect connections ### Updating Configuration -1. Connect to computer via USB -2. Modify config.h as needed -3. Re-upload sketch -4. Test new configuration +**NEW APPROACH - Field Configurable:** +1. Power off device +2. Remove SD card from device +3. Edit `tank_config.txt` on computer +4. Insert SD card back into device +5. Power on device - new configuration will be loaded and validated + +**CRITICAL**: Device will not start without valid SD card configuration. ### Data Retrieval 1. Remove SD card from system diff --git a/TankAlarm-092025-Client-Hologram/TankAlarm-092025-Client-Hologram.ino b/TankAlarm-092025-Client-Hologram/TankAlarm-092025-Client-Hologram.ino index aaf0ce2..5479d8b 100644 --- a/TankAlarm-092025-Client-Hologram/TankAlarm-092025-Client-Hologram.ino +++ b/TankAlarm-092025-Client-Hologram/TankAlarm-092025-Client-Hologram.ino @@ -195,44 +195,44 @@ bool powerFailureRecovery = false; #endif String logFileName = LOG_FILE_NAME; -// SD Card configuration variables (loaded from SD card config file) -String siteLocationName = SITE_LOCATION_NAME; -int tankNumber = TANK_NUMBER; -float inchesPerUnit = INCHES_PER_UNIT; -float tankHeightInches = TANK_HEIGHT_INCHES; -float highAlarmInches = HIGH_ALARM_INCHES; -float lowAlarmInches = LOW_ALARM_INCHES; -bool digitalHighAlarm = DIGITAL_HIGH_ALARM; -bool digitalLowAlarm = DIGITAL_LOW_ALARM; -float largeDecreaseThreshold = LARGE_DECREASE_THRESHOLD_INCHES; -int largeDecreaseWaitHours = LARGE_DECREASE_WAIT_HOURS; - -// Network and communication configuration (loaded from SD card) -String hologramDeviceKey = HOLOGRAM_DEVICE_KEY; -String serverDeviceKey = SERVER_DEVICE_KEY; // Server's device ID for remote commands -String alarmPhonePrimary = ALARM_PHONE_PRIMARY; -String alarmPhoneSecondary = ALARM_PHONE_SECONDARY; -String dailyReportPhone = DAILY_REPORT_PHONE; -String hologramAPN = HOLOGRAM_APN; - -// Timing configuration (loaded from SD card) -int sleepIntervalHours = SLEEP_INTERVAL_HOURS; -int dailyReportHours = DAILY_REPORT_HOURS; -String dailyReportTime = DAILY_REPORT_TIME; +// SD Card configuration variables (loaded from SD card config file - REQUIRED) +String siteLocationName = "Unknown Site"; +int tankNumber = 1; +float inchesPerUnit = 1.0; +float tankHeightInches = 120.0; +float highAlarmInches = 100.0; +float lowAlarmInches = 12.0; +bool digitalHighAlarm = true; +bool digitalLowAlarm = false; +float largeDecreaseThreshold = 24.0; +int largeDecreaseWaitHours = 2; + +// Network and communication configuration (loaded from SD card - REQUIRED) +String hologramDeviceKey = ""; +String serverDeviceKey = ""; // Server's device ID for remote commands +String alarmPhonePrimary = ""; +String alarmPhoneSecondary = ""; +String dailyReportPhone = ""; +String hologramAPN = "hologram"; + +// Timing configuration (loaded from SD card - REQUIRED) +int sleepIntervalHours = 1; +int dailyReportHours = 24; +String dailyReportTime = "05:00"; // Time synchronization variables bool timeIsSynced = false; unsigned long lastTimeSyncMillis = 0; const unsigned long TIME_SYNC_INTERVAL_MS = 24 * 60 * 60 * 1000; // Sync once per day -// Power management variables +// Power management variables (loaded from SD card - REQUIRED) volatile bool wakeFromCellular = false; // Flag set when woken by cellular data volatile int wakeReason = WAKE_REASON_TIMER; // Reason for last wake unsigned long lastCellularCheck = 0; // Last time we checked for cellular data -bool deepSleepMode = DEEP_SLEEP_MODE; // Whether to use deep sleep mode -int shortSleepMinutes = SHORT_SLEEP_MINUTES; // Short sleep duration for frequent checks -int normalSleepHours = NORMAL_SLEEP_HOURS; // Normal sleep duration between readings -bool wakeOnPingEnabled = ENABLE_WAKE_ON_PING; // Wake on ping functionality +bool deepSleepMode = false; // Whether to use deep sleep mode +int shortSleepMinutes = 10; // Short sleep duration for frequent checks +int normalSleepHours = 1; // Normal sleep duration between readings +bool wakeOnPingEnabled = true; // Wake on ping functionality // Height calibration system #define MAX_CALIBRATION_POINTS 10 @@ -270,16 +270,16 @@ void processSMSCommand(String command, String phoneNumber); void sendCalibrationSMS(String phoneNumber); float getCurrentSensorReading(); -// Network configuration (loaded from SD card) -int connectionTimeoutMs = CONNECTION_TIMEOUT_MS; -int smsRetryAttempts = SMS_RETRY_ATTEMPTS; +// Network configuration (loaded from SD card - REQUIRED) +int connectionTimeoutMs = 30000; +int smsRetryAttempts = 3; // Log file names (loaded from SD card) -String hourlyLogFile = SD_HOURLY_LOG_FILE; -String dailyLogFile = SD_DAILY_LOG_FILE; -String alarmLogFile = SD_ALARM_LOG_FILE; -String decreaseLogFile = SD_DECREASE_LOG_FILE; -String reportLogFile = SD_REPORT_LOG_FILE; +String hourlyLogFile = "hourly_log.txt"; +String dailyLogFile = "daily_log.txt"; +String alarmLogFile = "alarm_log.txt"; +String decreaseLogFile = "decrease_log.txt"; +String reportLogFile = "report_log.txt"; void setup() { // Initialize serial communication for debugging @@ -1008,22 +1008,27 @@ String getCurrentTimestamp() { // Load configuration from SD card void loadSDCardConfiguration() { if (!SD.begin(SD_CARD_CS_PIN)) { - logEvent("Failed to initialize SD card for configuration loading"); - return; + Serial.println("CRITICAL ERROR: Failed to initialize SD card for client configuration loading"); + Serial.println("SD card configuration is REQUIRED for operation"); + while (true) { + // Halt execution - SD card config is required + delay(5000); + Serial.println("Please insert SD card with tank_config.txt and restart"); + } } File configFile = SD.open(SD_CONFIG_FILE); if (!configFile) { -#ifdef ENABLE_SERIAL_DEBUG - if (ENABLE_SERIAL_DEBUG) Serial.println("Config file not found, using defaults"); -#endif - logEvent("Config file not found, using defaults from config.h"); - return; + Serial.println("CRITICAL ERROR: Client config file not found on SD card"); + Serial.println("tank_config.txt is REQUIRED for operation"); + while (true) { + // Halt execution - SD card config is required + delay(5000); + Serial.println("Please create tank_config.txt on SD card and restart"); + } } -#ifdef ENABLE_SERIAL_DEBUG - if (ENABLE_SERIAL_DEBUG) Serial.println("Loading configuration from SD card..."); -#endif + Serial.println("Loading client configuration from SD card..."); while (configFile.available()) { String line = configFile.readStringUntil('\n'); @@ -1109,15 +1114,28 @@ void loadSDCardConfiguration() { configFile.close(); - String configMsg = "Configuration loaded - Site: " + siteLocationName + + // Validate critical configuration + if (hologramDeviceKey.length() == 0 || hologramDeviceKey == "your_device_key_here") { + Serial.println("CRITICAL ERROR: HOLOGRAM_DEVICE_KEY not configured in tank_config.txt"); + while (true) { + delay(5000); + Serial.println("Please set HOLOGRAM_DEVICE_KEY in tank_config.txt and restart"); + } + } + + if (alarmPhonePrimary.length() == 0 || alarmPhonePrimary == "+12223334444") { + Serial.println("CRITICAL ERROR: ALARM_PHONE_PRIMARY not configured in tank_config.txt"); + while (true) { + delay(5000); + Serial.println("Please set ALARM_PHONE_PRIMARY in tank_config.txt and restart"); + } + } + + String configMsg = "Client configuration loaded successfully - Site: " + siteLocationName + ", Tank: " + String(tankNumber) + ", Height: " + String(tankHeightInches) + "in" + ", Daily Report: " + dailyReportTime; - logEvent(configMsg); - -#ifdef ENABLE_SERIAL_DEBUG - if (ENABLE_SERIAL_DEBUG) Serial.println(configMsg); -#endif + Serial.println(configMsg); } // Convert sensor reading to inches diff --git a/TankAlarm-092025-Client-Hologram/config_template.h b/TankAlarm-092025-Client-Hologram/config_template.h index 4802ac9..a913d4b 100644 --- a/TankAlarm-092025-Client-Hologram/config_template.h +++ b/TankAlarm-092025-Client-Hologram/config_template.h @@ -1,32 +1,18 @@ // // Configuration file for Tank Alarm 092025 -// Copy this file and rename to config.h, then update with your specific values +// This file now contains only essential compile-time constants +// Most configuration is now loaded from tank_config.txt on SD card // #ifndef CONFIG_H #define CONFIG_H -// Hologram.io Configuration -#define HOLOGRAM_DEVICE_KEY "your_device_key_here" // Replace with your actual device key -#define SERVER_DEVICE_KEY "server_device_key_here" // Server's Hologram device ID for remote commands -#define HOLOGRAM_APN "hologram" // Hologram.io APN (usually stays "hologram") - -// Phone Numbers for Notifications (include country code, e.g., +1 for US) -#define ALARM_PHONE_PRIMARY "+12223334444" // Primary emergency contact -#define ALARM_PHONE_SECONDARY "+15556667777" // Secondary emergency contact -#define DAILY_REPORT_PHONE "+18889990000" // Daily report recipient - -// Timing Configuration (in hours) -#define SLEEP_INTERVAL_HOURS 1 // How often to check tank level (default: 1 hour) -#define DAILY_REPORT_HOURS 24 // How often to send daily report (default: 24 hours) -#define DAILY_REPORT_TIME "05:00" // Time of day for daily report in HH:MM format (24-hour) - -// Pin Configuration (adjust if using different pins) +// Pin Configuration (hardware specific - cannot be changed at runtime) #define TANK_LEVEL_PIN 7 // Tank level sensor input pin #define RELAY_CONTROL_PIN 5 // Relay output control pin #define SD_CARD_CS_PIN 4 // SD card chip select pin (works for both MKR SD PROTO and MKR ETH shields) -// Tank Level Sensor Configuration +// Sensor Type Configuration (hardware specific) // Sensor Types: DIGITAL_FLOAT, ANALOG_VOLTAGE, CURRENT_LOOP #define SENSOR_TYPE DIGITAL_FLOAT // Type of tank level sensor @@ -35,75 +21,34 @@ #define SENSOR_DEBOUNCE_MS 100 // Debounce delay for sensor reading // Analog Voltage Sensor Configuration (SENSOR_TYPE = ANALOG_VOLTAGE) -// For Dwyer 626 series ratiometric 0.5-4.5V pressure sensors -// Can use A1-A4 pins on MKR RELAY shield with convenient screw terminals #define ANALOG_SENSOR_PIN A1 // Analog input pin for voltage sensor (A1, A2, A3, or A4) #define VOLTAGE_MIN 0.5 // Minimum sensor voltage (V) #define VOLTAGE_MAX 4.5 // Maximum sensor voltage (V) #define TANK_EMPTY_VOLTAGE 0.5 // Voltage when tank is empty (V) #define TANK_FULL_VOLTAGE 4.5 // Voltage when tank is full (V) -// Alarm thresholds are now configured in inches using HIGH_ALARM_INCHES and LOW_ALARM_INCHES -// See tank configuration section above for inches-based alarm settings - -// Multiple Analog Sensor Support (Optional - for multiple tank monitoring) -// Uncomment and configure additional sensors if needed -// #define ENABLE_MULTI_ANALOG_SENSORS true -// #define ANALOG_SENSOR_PIN_2 A2 // Second analog sensor -// #define ANALOG_SENSOR_PIN_3 A3 // Third analog sensor -// #define ANALOG_SENSOR_PIN_4 A4 // Fourth analog sensor // Current Loop Sensor Configuration (SENSOR_TYPE = CURRENT_LOOP) -// For 4-20mA sensors using NCD.io 4-channel current loop I2C module #define I2C_CURRENT_LOOP_ADDRESS 0x48 // I2C address of NCD.io module #define CURRENT_LOOP_CHANNEL 0 // Channel number (0-3) on NCD.io module #define CURRENT_MIN 4.0 // Minimum current (mA) #define CURRENT_MAX 20.0 // Maximum current (mA) #define TANK_EMPTY_CURRENT 4.0 // Current when tank is empty (mA) #define TANK_FULL_CURRENT 20.0 // Current when tank is full (mA) -// Alarm thresholds are now configured in inches using HIGH_ALARM_INCHES and LOW_ALARM_INCHES -// See tank configuration section above for inches-based alarm settings - -// Logging Configuration -#define LOG_FILE_NAME "tanklog.txt" // SD card log file name -#define ENABLE_SERIAL_DEBUG true // Enable/disable serial output for debugging -// Network Configuration -#define CONNECTION_TIMEOUT_MS 30000 // Network connection timeout (30 seconds) -#define SMS_RETRY_ATTEMPTS 3 // Number of retry attempts for SMS sending +// System Buffer Sizes and Hardware Limits (memory allocation at compile time) +#define MAX_CALIBRATION_POINTS 10 +#define CALIBRATION_FILE_NAME "calibration.txt" -// Power Management -#define ENABLE_LOW_POWER_MODE true // Enable low power sleep modes +// Network Configuration (timeouts and hardware limits) #define WAKE_CHECK_DURATION_MS 5000 // How long to stay awake for each check -#define SHORT_SLEEP_MINUTES 10 // Short sleep duration for active monitoring (minutes) -#define NORMAL_SLEEP_HOURS 1 // Normal sleep duration between readings (hours) -#define ENABLE_WAKE_ON_PING true // Enable wake-on-ping functionality -#define DEEP_SLEEP_MODE false // Use deep sleep mode for maximum power savings -// Tank Configuration for Inches/Feet Measurements -#define TANK_NUMBER 1 // Tank number identifier (1-99) -#define SITE_LOCATION_NAME "Your Site Name" // Site location name for reports -#define INCHES_PER_UNIT 1.0 // Inches per sensor unit (calibration factor) -#define TANK_HEIGHT_INCHES 120 // Total tank height in inches - -// Alarm Thresholds in Inches/Feet (for analog/current loop sensors) -#define HIGH_ALARM_INCHES 100 // High alarm threshold in inches -#define LOW_ALARM_INCHES 12 // Low alarm threshold in inches - -// Digital Float Switch Alarm Configuration (for DIGITAL_FLOAT sensors) -#define DIGITAL_HIGH_ALARM true // Enable high alarm for digital float -#define DIGITAL_LOW_ALARM false // Enable low alarm for digital float - -// Large Decrease Detection -#define ENABLE_LARGE_DECREASE_DETECTION true // Enable detection of large decreases -#define LARGE_DECREASE_THRESHOLD_INCHES 24 // Threshold for large decrease in inches -#define LARGE_DECREASE_WAIT_HOURS 2 // Hours to wait before logging large decrease +// Logging Configuration (system limits) +#define ENABLE_SERIAL_DEBUG true // Enable/disable serial output for debugging +#define LOG_FILE_NAME "tanklog.txt" // SD card log file name // SD Card Configuration Files #define SD_CONFIG_FILE "tank_config.txt" // SD card configuration file -#define SD_HOURLY_LOG_FILE "hourly_log.txt" // Hourly data log file -#define SD_DAILY_LOG_FILE "daily_log.txt" // Daily report log file -#define SD_ALARM_LOG_FILE "alarm_log.txt" // Alarm event log file -#define SD_DECREASE_LOG_FILE "decrease_log.txt" // Large decrease log file -#define SD_REPORT_LOG_FILE "report_log.txt" // Daily report transmission log file + +// No fallback defaults - SD card configuration is required #endif // CONFIG_H \ No newline at end of file diff --git a/TankAlarm-092025-Client-Hologram/tank_config_example.txt b/TankAlarm-092025-Client-Hologram/tank_config_example.txt index 1d1ece1..c7818cc 100644 --- a/TankAlarm-092025-Client-Hologram/tank_config_example.txt +++ b/TankAlarm-092025-Client-Hologram/tank_config_example.txt @@ -1,17 +1,18 @@ -# Tank Alarm Configuration File +# Tank Alarm Configuration File (REQUIRED) # Copy this file to SD card as tank_config.txt and modify values as needed # Lines starting with # are comments and will be ignored +# ALL SETTINGS ARE REQUIRED - Tank will not start without valid configuration -# Site Information +# Site Information (REQUIRED) SITE_NAME=Example Tank Farm TANK_NUMBER=1 -# Hologram.io Configuration +# Hologram.io Configuration (REQUIRED) HOLOGRAM_DEVICE_KEY=abc123def456ghi789 SERVER_DEVICE_KEY=xyz987uvw654rst321 HOLOGRAM_APN=hologram -# Phone Numbers for Notifications (include country code) +# Phone Numbers for Notifications (REQUIRED - include country code) ALARM_PHONE_PRIMARY=+15551234567 ALARM_PHONE_SECONDARY=+15559876543 DAILY_REPORT_PHONE=+15555551234 diff --git a/TankAlarm-092025-Server-Hologram/INSTALLATION.md b/TankAlarm-092025-Server-Hologram/INSTALLATION.md index acdb8f9..2d57d07 100644 --- a/TankAlarm-092025-Server-Hologram/INSTALLATION.md +++ b/TankAlarm-092025-Server-Hologram/INSTALLATION.md @@ -84,27 +84,34 @@ Install these libraries via **Tools → Manage Libraries**: 3. Open `TankAlarm-092025-Server-Hologram.ino` in Arduino IDE ### Configure Settings -1. **Copy Configuration Template**: + +#### SD Card Configuration (REQUIRED) +The server now requires configuration via SD card. Fallback to compile-time defaults has been removed. + +1. **Copy Configuration Template to SD Card**: ```bash - cp server_config_template.h server_config.h + cp server_config.txt /path/to/sd/card/server_config.txt ``` -2. **Edit Configuration** (`server_config.h`): - ```cpp - // Update these values for your setup - #define HOLOGRAM_DEVICE_KEY "your_actual_device_key_here" - #define DAILY_EMAIL_RECIPIENT "+15551234567@vtext.com" - #define DAILY_EMAIL_HOUR 6 // 6 AM for daily reports +2. **Edit SD Card Configuration** (`server_config.txt` on SD card): ``` - -3. **Network Configuration** (optional): - ```cpp - // Static IP settings (used if DHCP fails) - #define STATIC_IP_ADDRESS {192, 168, 1, 100} - #define STATIC_GATEWAY {192, 168, 1, 1} - #define STATIC_SUBNET {255, 255, 255, 0} + # Update these values for your setup - ALL SETTINGS REQUIRED + HOLOGRAM_DEVICE_KEY=your_actual_device_key_here + DAILY_EMAIL_RECIPIENT=+15551234567@vtext.com + DAILY_EMAIL_HOUR=6 + SERVER_LOCATION=Your Location Name ``` +3. **Insert SD Card**: Place configured SD card in server before powering on + +**IMPORTANT**: The server will not start without a properly configured `server_config.txt` file on the SD card. The device will halt with error messages if: +- SD card is not inserted +- `server_config.txt` file is missing +- HOLOGRAM_DEVICE_KEY is not set or is still the default value + +#### Legacy Compile-Time Configuration (No Longer Used) +The `server_config.h` file now only contains essential hardware constants. Configuration values are no longer read from this file. + ### Upload Code to Device 1. **Connect Hardware**: - Connect MKR NB 1500 to computer via USB @@ -261,16 +268,41 @@ Enable detailed logging by setting in `server_config.h`: ### Common Configuration Files -#### Example server_config.h +#### Example server_config.txt (SD Card Configuration - REQUIRED) +``` +# Tank Alarm Server SD Card Configuration - ALL VALUES REQUIRED +HOLOGRAM_DEVICE_KEY=1234567890abcdef +DAILY_EMAIL_RECIPIENT=+15551234567@vtext.com +DAILY_EMAIL_HOUR=6 +DAILY_EMAIL_MINUTE=0 +SERVER_LOCATION=Main Office +ENABLE_SERIAL_DEBUG=true +STATIC_IP_ADDRESS=192,168,1,100 +STATIC_GATEWAY=192,168,1,1 +STATIC_SUBNET=255,255,255,0 +``` + +#### server_config.h (Hardware Constants Only) ```cpp -#define HOLOGRAM_DEVICE_KEY "1234567890abcdef" -#define DAILY_EMAIL_RECIPIENT "+15551234567@vtext.com" -#define DAILY_EMAIL_HOUR 6 -#define DAILY_EMAIL_MINUTE 0 -#define STATIC_IP_ADDRESS {192, 168, 1, 100} -#define ENABLE_SERIAL_DEBUG true +// Only hardware-specific constants remain +#define SD_CARD_CS_PIN 4 +#define CONNECTION_TIMEOUT_MS 30000 +#define WEB_SERVER_PORT 80 +#define MESSAGE_BUFFER_SIZE 1024 +// No fallback defaults - SD card configuration is required ``` +#### Field Configuration Updates (CRITICAL) +To update configuration in the field: +1. **Power off** the server (REQUIRED) +2. **Remove SD card** from server +3. **Edit** `server_config.txt` on a computer +4. **Verify** all required settings are present +5. **Insert SD card** back into server +6. **Power on** server - configuration will be validated and loaded + +**WARNING**: Server will not start without valid SD card configuration. + #### Hologram Device Key Location Find your device key in the Hologram.io dashboard: 1. Login to dashboard.hologram.io diff --git a/TankAlarm-092025-Server-Hologram/SD_CARD_CONFIG.md b/TankAlarm-092025-Server-Hologram/SD_CARD_CONFIG.md new file mode 100644 index 0000000..c5faebd --- /dev/null +++ b/TankAlarm-092025-Server-Hologram/SD_CARD_CONFIG.md @@ -0,0 +1,102 @@ +# SD Card Configuration for Tank Alarm Server (REQUIRED) + +The Tank Alarm Server requires configuration via SD card. The server will not start without a properly configured SD card. + +## Quick Start + +1. Copy `server_config.txt` to the root of your SD card +2. Edit the configuration values as needed +3. Insert SD card into server and power on + +**CRITICAL**: The server will halt with error messages if the SD card or configuration file is missing. + +## Configuration File Format + +The configuration file uses a simple `KEY=VALUE` format: + +``` +# Comments start with # +HOLOGRAM_DEVICE_KEY=your_device_key_here +DAILY_EMAIL_HOUR=6 +SERVER_LOCATION=Main Office +``` + +## Available Configuration Options + +### Required Settings +- `HOLOGRAM_DEVICE_KEY`: Your Hologram.io device key +- `DAILY_EMAIL_RECIPIENT`: Email address for daily reports +- `SERVER_LOCATION`: Descriptive location name + +### Network Settings +- `STATIC_IP_ADDRESS`: Static IP (format: 192,168,1,100) +- `STATIC_GATEWAY`: Gateway IP (format: 192,168,1,1) +- `STATIC_SUBNET`: Subnet mask (format: 255,255,255,0) +- `ETHERNET_MAC_BYTE_1` through `ETHERNET_MAC_BYTE_6`: MAC address bytes + +### Email/Notification Settings +- `DAILY_EMAIL_HOUR`: Hour to send daily report (0-23) +- `DAILY_EMAIL_MINUTE`: Minute to send daily report (0-59) +- `ALARM_EMAIL_RECIPIENT`: Email for alarm notifications +- `USE_HOLOGRAM_EMAIL`: Use Hologram API for email (true/false) + +### System Settings +- `ENABLE_SERIAL_DEBUG`: Enable debug output (true/false) +- `WEB_PAGE_REFRESH_SECONDS`: Web page auto-refresh interval +- `MAX_REPORTS_IN_MEMORY`: Maximum reports to store in memory (maximum: 100, will be capped if exceeded) +- `DAYS_TO_KEEP_LOGS`: Days to retain log files + +### Monthly Reports +- `MONTHLY_REPORT_ENABLED`: Enable monthly reports (true/false) +- `MONTHLY_REPORT_DAY`: Day of month to generate report (1-28) +- `MONTHLY_REPORT_HOUR`: Hour to generate report (0-23) + +## Field Updates + +To update configuration in the field: + +1. **Power off** the server +2. **Remove SD card** from server +3. **Edit** `server_config.txt` on a computer +4. **Insert SD card** back into server +5. **Power on** server - new configuration will be loaded + +## Fallback Behavior + +**NO FALLBACK**: If `server_config.txt` is not found on the SD card, the server will: +- Display critical error messages on serial console +- Halt execution and refuse to start +- Require operator intervention to insert SD card with proper configuration + +The server assumes SD card configuration will always be available and does not fall back to compile-time defaults. + +## Troubleshooting + +### Configuration not loading +- **CRITICAL**: Check that SD card is properly inserted and detected +- **CRITICAL**: Check that file is named exactly `server_config.txt` +- **CRITICAL**: Verify HOLOGRAM_DEVICE_KEY is set and not the default placeholder +- Check serial output for specific error messages +- Ensure no extra spaces around `=` in config file +- Server will halt execution if configuration is missing or invalid + +### Invalid values +- Boolean values must be exactly `true` or `false` +- IP addresses must use comma format: `192,168,1,100` +- No quotes needed around string values +- Comments must start with `#` at beginning of line + +## Example Complete Configuration + +``` +# Tank Alarm Server Configuration +HOLOGRAM_DEVICE_KEY=1234567890abcdef +SERVER_LOCATION=Tank Farm A +DAILY_EMAIL_HOUR=6 +DAILY_EMAIL_MINUTE=30 +DAILY_EMAIL_RECIPIENT=alerts@company.com +ENABLE_SERIAL_DEBUG=false +STATIC_IP_ADDRESS=192,168,1,100 +MONTHLY_REPORT_ENABLED=true +MONTHLY_REPORT_DAY=1 +``` \ No newline at end of file diff --git a/TankAlarm-092025-Server-Hologram/TankAlarm-092025-Server-Hologram.ino b/TankAlarm-092025-Server-Hologram/TankAlarm-092025-Server-Hologram.ino index b3c6aa4..57c5361 100644 --- a/TankAlarm-092025-Server-Hologram/TankAlarm-092025-Server-Hologram.ino +++ b/TankAlarm-092025-Server-Hologram/TankAlarm-092025-Server-Hologram.ino @@ -80,7 +80,7 @@ String dailyEmailAttemptDate = ""; bool dailyEmailPending = false; unsigned long lastDailyEmailRetry = 0; const unsigned long DAILY_EMAIL_RETRY_INTERVAL = 1800000; // 30 minutes in milliseconds -const int MAX_TANK_REPORTS = 50; // Maximum number of reports to store in memory +const int MAX_TANK_REPORTS = 100; // Maximum array size (actual limit from configuration) TankReport tankReports[MAX_TANK_REPORTS]; int reportCount = 0; @@ -115,6 +115,39 @@ const int MAX_POWER_FAILURE_EVENTS = 50; PowerFailureEvent powerFailureEvents[MAX_POWER_FAILURE_EVENTS]; int powerFailureEventCount = 0; +// Server configuration variables (loaded from SD card config file - REQUIRED) +String hologramDeviceKey = ""; +int dailyEmailHour = 6; +int dailyEmailMinute = 0; +bool useHologramEmail = true; +String dailyEmailSmsGateway = ""; +String hologramEmailRecipient = ""; +String dailyEmailRecipient = ""; +String serverName = "Tank Alarm Server"; +String serverLocation = "Unknown Location"; +bool enableSerialDebug = true; +int webPageRefreshSeconds = 30; +int maxReportsInMemory = 50; +int daysToKeepLogs = 30; +int staticIpAddress[4] = {192, 168, 1, 100}; +int staticGateway[4] = {192, 168, 1, 1}; +int staticSubnet[4] = {255, 255, 255, 0}; +int hologramCheckIntervalMs = 5000; +bool forwardAlarmsToEmail = true; +String alarmEmailRecipient = ""; +bool monthlyReportEnabled = true; +int monthlyReportDay = 1; +int monthlyReportHour = 8; +int ethernetMacByte1 = 0x90; +int ethernetMacByte2 = 0xA2; +int ethernetMacByte3 = 0xDA; +int ethernetMacByte4 = 0x10; +int ethernetMacByte5 = 0xD1; +int ethernetMacByte6 = 0x72; + +// SD card configuration file +#define SERVER_CONFIG_FILE "server_config.txt" + void setup() { // Initialize serial communication for debugging Serial.begin(9600); @@ -133,10 +166,21 @@ void setup() { } else { Serial.println("SD card initialized successfully"); + // Load server configuration from SD card + loadServerConfigurationFromSD(); + // Check for power failure recovery checkPowerFailureRecovery(); } + // Update MAC address with loaded configuration + mac[0] = ethernetMacByte1; + mac[1] = ethernetMacByte2; + mac[2] = ethernetMacByte3; + mac[3] = ethernetMacByte4; + mac[4] = ethernetMacByte5; + mac[5] = ethernetMacByte6; + // Initialize Ethernet connection with retry logic initializeEthernet(); @@ -316,7 +360,7 @@ void processDailyReport(String reportData) { } // Store report in memory - if (reportCount < MAX_TANK_REPORTS) { + if (reportCount < maxReportsInMemory && reportCount < MAX_TANK_REPORTS) { tankReports[reportCount] = report; reportCount++; } @@ -461,7 +505,7 @@ void sendWebPage(EthernetClient &client) { client.println(""); client.println(""); client.println("Tank Alarm Server - Dashboard"); - client.println(""); // Auto refresh every 30 seconds + client.println(""); // Auto refresh based on configuration client.println("