Skip to content

Commit 73cca69

Browse files
Enhance dashboard and chemistry configuration with firmware support
- Updated dashboard scripts to set firmware version in the body attributes based on equipment data. - Enhanced chemistry configuration to support Intellichem standalone mode, including UI elements for standalone options and tooltips. - Added new configuration options for freeze cycle time and override settings in the general configuration based on firmware version. - Improved message list widget to handle row expansion with visual hints for better user interaction. - Updated CSS styles for message management and row expansion indicators to enhance visual feedback. tagyoureit/nodejs-poolController#1136
1 parent c624044 commit 73cca69

7 files changed

Lines changed: 259 additions & 81 deletions

File tree

scripts/config/chemistry.js

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(function ($) {
1+
(function ($) {
22
$.widget('pic.configChemistry', {
33
options: {},
44
_create: function () {
@@ -33,6 +33,11 @@
3333
});
3434
$.getApiService('/config/options/chemControllers', null, 'Loading Options...', function (opts, status, xhr) {
3535
chemOpts = opts;
36+
var standaloneSupported = typeof opts.intellichemStandaloneSupported !== 'undefined'
37+
? makeBool(opts.intellichemStandaloneSupported)
38+
: (($('body').attr('data-controllertype') || '').toLowerCase() === 'nixie');
39+
var standaloneEnabledMessage = 'Standalone mode keeps IntelliChem communication active even when the pool body is off. Use for Intellichem-only systems.';
40+
var standaloneUnsupportedMessage = 'Standalone mode is only available when Nixie directly controls IntelliChem.';
3641
for (var i = 0; i < opts.controllers.length; i++) {
3742
$('<div></div>').appendTo(pnl).pnlChemControllerConfig(opts)[0].dataBind(opts.controllers[i]);
3843
}
@@ -190,6 +195,7 @@
190195
case 'intellichem':
191196
cc.name = 'IntelliChem';
192197
cc.address = 144;
198+
cc.intellichemStandalone = standaloneSupported && !!data.intellichemStandalone;
193199
cc.ph = { setpoint: 7.4, dosingMethod: 0, flowReadingsOnly: true, tolerance: { enabled: true, low: 7.2, high: 7.6 }, phSupply: 1, acidType: 5, tank: { alarmEmptyEnabled: true, alarmEmptyLevel: 20 } };
194200
cc.orp = { setpoint: 750, dosingMethod: 0, flowReadingsOnly: true, tolerance: { enabled: true, low: 650, high: 800 }, phLockout: 7.8, tank: { alarmEmptyEnabled: true, alarmEmptyLevel: 20 } };
195201
break;
@@ -213,7 +219,7 @@
213219
}
214220
$('<div></div>').css({ textAlign: 'center' }).appendTo(divSelection).append('<i class="fas fa-flask" style="font-size:30pt;"></i>');
215221
$('<div></div>').css({ textAlign: 'center' }).appendTo(divSelection).text('Chem Controller');
216-
$('<div></div>').appendTo(divSelection).pickList({
222+
var chemTypePick = $('<div></div>').appendTo(divSelection).pickList({
217223
required: true,
218224
style: { textAlign: 'left' },
219225
bindColumn: 0, displayColumn: 2, labelText: 'Chem Controller Type<br/>', binding: 'type',
@@ -224,9 +230,30 @@
224230
e.stopPropagation();
225231
}).on('mousedown', function (e) {
226232
e.stopImmediatePropagation();
227-
228233
});
229-
234+
var standaloneOpt = $('<div></div>').appendTo(divSelection).checkbox({
235+
labelText: 'Intellichem Standalone',
236+
binding: 'intellichemStandalone'
237+
}).css({ marginTop: '.25rem', textAlign: 'left' })
238+
.on('mousedown', function (e) { e.stopImmediatePropagation(); })
239+
.on('click', function (e) { e.stopPropagation(); })
240+
.hide();
241+
var standaloneInfo = $('<span></span>').appendTo(divSelection)
242+
.css({ marginLeft: '.35rem', cursor: 'help', display: 'none' })
243+
.append('<i class="fas fa-info-circle"></i>');
244+
var updateStandaloneOption = function (selectedType) {
245+
var isIntellichem = typeof selectedType !== 'undefined' && selectedType !== null && selectedType.name === 'intellichem';
246+
if (!isIntellichem || !standaloneSupported) {
247+
standaloneOpt.hide();
248+
standaloneInfo.hide();
249+
if (standaloneOpt[0] && typeof standaloneOpt[0].val === 'function') standaloneOpt[0].val(false);
250+
return;
251+
}
252+
standaloneOpt.show();
253+
standaloneInfo.show();
254+
if (standaloneOpt[0] && typeof standaloneOpt[0].disabled === 'function') standaloneOpt[0].disabled(false);
255+
};
256+
chemTypePick.on('selchanged', function (evt) { updateStandaloneOption(evt.newItem); });
230257
divSelection = $('<div></div>').addClass('picButton').addClass('chemController-type').addClass('chemDoser').addClass('btn').css({ width: '157px', height: '97px', verticalAlign: 'middle' })
231258
.appendTo(line)
232259
.on('mouseover', function (e) { $(e.currentTarget).addClass('button-hover'); })
@@ -1158,6 +1185,44 @@
11581185
columns: [{ binding: 'val', hidden: true, text: 'Address' }, { binding: 'desc', text: 'Address' }],
11591186
items: addresses, inputAttrs: { style: { width: '3rem' } }, labelAttrs: { style: { marginLeft: '.25rem' } }
11601187
});
1188+
$('<div></div>').appendTo(line).checkbox({
1189+
labelText: 'Intellichem Standalone',
1190+
binding: binding + 'intellichemStandalone'
1191+
}).addClass('pnl-intellichem-standalone')
1192+
.hide();
1193+
var standaloneTipMessage = 'Standalone mode keeps IntelliChem communication active even when the pool body is off. Use for Intellichem-only systems.';
1194+
var standaloneInfo = $('<span></span>').appendTo(line)
1195+
.addClass('pnl-intellichem-standalone')
1196+
.css({ marginLeft: '.25rem', cursor: 'help', display: 'none' })
1197+
.attr('tabindex', 0)
1198+
.attr('data-tip-message', standaloneTipMessage);
1199+
$('<i class="fas fa-info-circle"></i>').appendTo(standaloneInfo);
1200+
var showStandaloneTip = function () {
1201+
$.pic.fieldTip.clearTips(line);
1202+
var tipMessage = standaloneInfo.attr('data-tip-message') || standaloneTipMessage;
1203+
var tipContent = $('<div></div>').css({
1204+
maxWidth: '22rem',
1205+
whiteSpace: 'normal',
1206+
lineHeight: '1.25rem'
1207+
}).text(tipMessage);
1208+
$.pic.fieldTip.showTip(line, {
1209+
field: standaloneInfo,
1210+
message: tipContent,
1211+
closeAfter: 5000,
1212+
placement: { my: 'right top', at: 'right bottom+8' }
1213+
});
1214+
setTimeout(function () {
1215+
line.find('div.picFieldTip:last')
1216+
.addClass('intellichem-standalone-tip')
1217+
.removeClass('left right')
1218+
.addClass('bottom');
1219+
}, 0);
1220+
};
1221+
standaloneInfo
1222+
.on('mouseenter focusin click', function (evt) {
1223+
evt.stopPropagation();
1224+
showStandaloneTip();
1225+
});
11611226
$('<hr></hr>').appendTo(pnl);
11621227
$('<div></div>').appendTo(pnl).addClass('pnl-chemcontroller-type');
11631228

@@ -1208,6 +1273,11 @@
12081273
var cols = acc[0].columns();
12091274
cols[0].elText().text(obj.name);
12101275
var type = o.types.find(elem => elem.val === obj.type);
1276+
var standaloneSupported = typeof o.intellichemStandaloneSupported !== 'undefined'
1277+
? makeBool(o.intellichemStandaloneSupported)
1278+
: (($('body').attr('data-controllertype') || '').toLowerCase() === 'nixie');
1279+
var standaloneEnabledMessage = 'Standalone mode keeps IntelliChem communication active even when the pool body is off. Use for Intellichem-only systems.';
1280+
var standaloneUnsupportedMessage = 'Standalone mode is only available when Nixie directly controls IntelliChem.';
12111281
cols[1].elText().text(typeof type !== 'undefined' ? type.desc : 'Controller');
12121282

12131283
var ctype = el.attr('data-controllertype');
@@ -1258,10 +1328,27 @@
12581328
if (typeof obj.orp === 'undefined') obj.orp = {
12591329
mixingTime: 60, maxDosingTime: 20, pump: {}, probe: {}, tank: {}
12601330
};
1331+
if (typeof obj.intellichemStandalone === 'undefined') obj.intellichemStandalone = false;
12611332
self.splitSeconds('mixingTime', obj.ph, obj.ph.mixingTime);
12621333
self.splitSeconds('mixingTime', obj.orp, obj.orp.mixingTime);
12631334
self.splitSeconds('maxDosingTime', obj.ph, obj.ph.maxDosingTime);
12641335
self.splitSeconds('maxDosingTime', obj.orp, obj.orp.maxDosingTime);
1336+
el.find('div.picCheckbox[data-bind="intellichemStandalone"]').each(function () {
1337+
if (type.name === 'intellichem') {
1338+
$(this).show();
1339+
if (typeof this.disabled === 'function') this.disabled(!standaloneSupported);
1340+
if (!standaloneSupported && typeof this.val === 'function') this.val(false);
1341+
}
1342+
else $(this).hide();
1343+
});
1344+
el.find('span.pnl-intellichem-standalone').each(function () {
1345+
if (type.name === 'intellichem') {
1346+
$(this).show();
1347+
var tip = standaloneSupported ? standaloneEnabledMessage : standaloneUnsupportedMessage;
1348+
$(this).attr('data-tip-message', tip);
1349+
}
1350+
else $(this).hide();
1351+
});
12651352
if (type.hasAddress) {
12661353
el.find('*[data-bind="address"]').each(function () {
12671354
$(this).show();

scripts/config/general.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(function ($) {
1+
(function ($) {
22
$.widget('pic.configGeneral', {
33
options: {},
44
_create: function () {
@@ -223,6 +223,26 @@
223223
});
224224
}
225225
if (controller !== 'nixie') $('<div></div>').appendTo(line).checkbox({ labelText: 'Heater Cooldown Delay', binding: 'options.cooldownDelay' });
226+
var firmware = parseFloat($('body').attr('data-firmware') || '0');
227+
if (controller === 'intellicenter' && firmware >= 3.008) {
228+
line = $('<div></div>').appendTo(pnl);
229+
$('<div></div>').appendTo(line).valueSpinner({
230+
canEdit: true, labelText: 'Freeze Cycle Time', binding: 'options.freezeCycleTime', dataType: 'number', fmtType: '#,##0', min: 1, max: 60, step: 1, maxlength: 3,
231+
units: 'min', labelAttrs: { style: { width: '14rem', display: 'inline-block' } }, inputAttrs: { style: { width: '4.5rem' } }
232+
});
233+
line = $('<div></div>').appendTo(pnl);
234+
$('<div></div>').appendTo(line).pickList({
235+
labelText: 'Freeze Override', binding: 'options.freezeOverride', bindColumn: 0,
236+
columns: [{ binding: 'val', hidden: true, text: 'Val' }, { binding: 'desc', text: 'Duration' }],
237+
items: [
238+
{ val: 30, desc: '30 minutes' },
239+
{ val: 90, desc: '90 minutes (1.5 hrs)' },
240+
{ val: 150, desc: '150 minutes (2.5 hrs)' },
241+
{ val: 210, desc: '210 minutes (3.5 hrs)' }
242+
],
243+
inputAttrs: { style: { width: '14rem' } }, labelAttrs: { style: { width: '14rem', display: 'inline-block' } }
244+
});
245+
}
226246
btnPnl = $('<div class="picBtnPanel btn-panel"></div>').appendTo(pnl);
227247
btnSave = $('<div id="btnSaveDelays"></div>').appendTo(btnPnl).actionButton({ text: 'Save Delays', icon: '<i class="fas fa-save"></i>' });
228248
btnSave.on('click', function (e) {

scripts/dashboard.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(function ($) {
1+
(function ($) {
22
$.widget("pic.dashboard", {
33
options: { socket: null },
44
_create: function () {
@@ -113,6 +113,7 @@
113113
$('body').attr('data-apiproxy', o.useProxy);
114114
$.getApiService('/state/all', null, function (data, status, xhr) {
115115
self._setControllerType(data.controllerType);
116+
if (typeof data.equipment !== 'undefined') $('body').attr('data-firmware', data.equipment.softwareVersion || '');
116117
//if (data.equipment.model.startsWith('IntelliCenter')) {
117118
// $('div.picDashboard').attr('data-controllertype', 'IntelliCenter');
118119
// $('div.picDashboard').attr('data-hidethemes', 'false');
@@ -160,6 +161,7 @@
160161
$('body').attr('data-apiproxy', o.useProxy);
161162
$.getApiService('/state/all', null, function (data, status, xhr) {
162163
if (typeof data.equipment === 'undefined' || typeof data.equipment.model === 'undefined') { self._clearPanels(); return; }
164+
$('body').attr('data-firmware', data.equipment.softwareVersion || '');
163165
if (data.equipment.model.startsWith('IntelliCenter')) {
164166
$('div.picDashboard').attr('data-controllertype', 'IntelliCenter');
165167
$('div.picDashboard').attr('data-hidethemes', 'false');

0 commit comments

Comments
 (0)