Skip to content

Commit f4b6159

Browse files
Copilotdorkmo
andcommitted
Add SMS Alert section with per-alarm trigger and multiple phone numbers support
- Add "+ Add SMS Alert" button (visible after alarm is configured) - SMS Alert section includes: - Phone numbers field (comma-separated for multiple recipients) - Trigger type (High Alarm Only, Low Alarm Only, Any Alarm) - Custom message field (optional) - Tooltip on phone numbers field explaining format - Validation warning if SMS trigger doesn't match enabled alarm type - Config output includes smsAlert object with phones array, trigger, and message Co-authored-by: dorkmo <[email protected]>
1 parent dc4d85e commit f4b6159

File tree

1 file changed

+73
-2
lines changed

1 file changed

+73
-2
lines changed

TankAlarm-112025-Server-BluesOpta/TankAlarm-112025-Server-BluesOpta.ino

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,22 @@ static const char CONFIG_GENERATOR_HTML[] PROGMEM = R"HTML(
786786
</label>
787787
</div>
788788
</div>
789+
790+
<button type="button" class="add-section-btn add-sms-btn hidden" onclick="toggleSmsSection(${id})">+ Add SMS Alert</button>
791+
<div class="collapsible-section sms-section">
792+
<h4 style="margin: 16px 0 8px; font-size: 0.95rem; border-top: 1px solid var(--card-border); padding-top: 12px;">SMS Alert Notifications <button type="button" class="remove-btn" onclick="removeSmsSection(${id})" style="float: right;">Remove SMS Alert</button></h4>
793+
<div class="form-grid">
794+
<label class="field" style="grid-column: 1 / -1;"><span>Phone Numbers<span class="tooltip-icon" tabindex="0" data-tooltip="Enter phone numbers with country code (e.g., +15551234567). Separate multiple numbers with commas.">?</span></span><input type="text" class="sms-phones" placeholder="+15551234567, +15559876543"></label>
795+
<label class="field"><span>Trigger On</span>
796+
<select class="sms-trigger">
797+
<option value="any">Any Alarm (High or Low)</option>
798+
<option value="high">High Alarm Only</option>
799+
<option value="low">Low Alarm Only</option>
800+
</select>
801+
</label>
802+
<label class="field" style="grid-column: span 2;"><span>Custom Message (optional)</span><input type="text" class="sms-message" placeholder="Tank alarm triggered"></label>
803+
</div>
804+
</div>
789805
</div>
790806
`;
791807
}
@@ -808,23 +824,29 @@ static const char CONFIG_GENERATOR_HTML[] PROGMEM = R"HTML(
808824
const alarmSection = card.querySelector('.alarm-section');
809825
const addAlarmBtn = card.querySelector('.add-alarm-btn');
810826
const addRelayBtn = card.querySelector('.add-relay-btn');
827+
const addSmsBtn = card.querySelector('.add-sms-btn');
811828
alarmSection.classList.add('visible');
812829
addAlarmBtn.classList.add('hidden');
813-
// Show relay button now that alarms are configured
830+
// Show relay and SMS buttons now that alarms are configured
814831
addRelayBtn.classList.remove('hidden');
832+
addSmsBtn.classList.remove('hidden');
815833
};
816834
817835
window.removeAlarmSection = function(id) {
818836
const card = document.getElementById(`sensor-${id}`);
819837
const alarmSection = card.querySelector('.alarm-section');
820838
const addAlarmBtn = card.querySelector('.add-alarm-btn');
821839
const addRelayBtn = card.querySelector('.add-relay-btn');
840+
const addSmsBtn = card.querySelector('.add-sms-btn');
822841
const relaySection = card.querySelector('.relay-section');
842+
const smsSection = card.querySelector('.sms-section');
823843
alarmSection.classList.remove('visible');
824844
addAlarmBtn.classList.remove('hidden');
825-
// Hide relay button and section when alarms are removed
845+
// Hide relay and SMS buttons and sections when alarms are removed
826846
addRelayBtn.classList.add('hidden');
847+
addSmsBtn.classList.add('hidden');
827848
relaySection.classList.remove('visible');
849+
smsSection.classList.remove('visible');
828850
// Reset alarm values to defaults
829851
card.querySelector('.high-alarm').value = '100';
830852
card.querySelector('.low-alarm').value = '20';
@@ -837,6 +859,10 @@ static const char CONFIG_GENERATOR_HTML[] PROGMEM = R"HTML(
837859
['relay-1', 'relay-2', 'relay-3', 'relay-4'].forEach(cls => {
838860
card.querySelector('.' + cls).checked = false;
839861
});
862+
// Reset SMS values
863+
card.querySelector('.sms-phones').value = '';
864+
card.querySelector('.sms-trigger').value = 'any';
865+
card.querySelector('.sms-message').value = '';
840866
};
841867
842868
window.toggleRelaySection = function(id) {
@@ -862,6 +888,26 @@ static const char CONFIG_GENERATOR_HTML[] PROGMEM = R"HTML(
862888
});
863889
};
864890
891+
window.toggleSmsSection = function(id) {
892+
const card = document.getElementById(`sensor-${id}`);
893+
const smsSection = card.querySelector('.sms-section');
894+
const addBtn = card.querySelector('.add-sms-btn');
895+
smsSection.classList.add('visible');
896+
addBtn.classList.add('hidden');
897+
};
898+
899+
window.removeSmsSection = function(id) {
900+
const card = document.getElementById(`sensor-${id}`);
901+
const smsSection = card.querySelector('.sms-section');
902+
const addBtn = card.querySelector('.add-sms-btn');
903+
smsSection.classList.remove('visible');
904+
addBtn.classList.remove('hidden');
905+
// Reset SMS values
906+
card.querySelector('.sms-phones').value = '';
907+
card.querySelector('.sms-trigger').value = 'any';
908+
card.querySelector('.sms-message').value = '';
909+
};
910+
865911
window.updateMonitorFields = function(id) {
866912
const card = document.getElementById(`sensor-${id}`);
867913
const type = card.querySelector('.monitor-type').value;
@@ -1049,6 +1095,31 @@ static const char CONFIG_GENERATOR_HTML[] PROGMEM = R"HTML(
10491095
}
10501096
}
10511097
1098+
// Check if SMS section is enabled
1099+
const smsSectionVisible = card.querySelector('.sms-section').classList.contains('visible');
1100+
if (smsSectionVisible) {
1101+
const smsPhones = card.querySelector('.sms-phones').value.trim();
1102+
const smsTrigger = card.querySelector('.sms-trigger').value;
1103+
const smsMessage = card.querySelector('.sms-message').value.trim();
1104+
1105+
if (smsPhones) {
1106+
// Parse phone numbers (comma separated) into array
1107+
const phoneArray = smsPhones.split(',').map(p => p.trim()).filter(p => p.length > 0);
1108+
if (phoneArray.length > 0) {
1109+
tank.smsAlert = {
1110+
phones: phoneArray,
1111+
trigger: smsTrigger, // 'any', 'high', or 'low'
1112+
message: smsMessage || 'Tank alarm triggered'
1113+
};
1114+
// Validation: warn if SMS trigger is set to an alarm type that is not enabled
1115+
if ((smsTrigger === 'high' && !highAlarmEnabled) ||
1116+
(smsTrigger === 'low' && !lowAlarmEnabled)) {
1117+
alert(`Warning: SMS Alert for ${name} is set to trigger on "${smsTrigger}" alarm, but that alarm type is not enabled.`);
1118+
}
1119+
}
1120+
}
1121+
}
1122+
10521123
config.tanks.push(tank);
10531124
});
10541125

0 commit comments

Comments
 (0)