From cbc9badd3fcc2c394e7a8b9b5ff32e137cda7f48 Mon Sep 17 00:00:00 2001 From: Hypnos <12692680+Hypnos3@users.noreply.github.com> Date: Mon, 4 Nov 2019 12:58:57 +0100 Subject: [PATCH 1/8] 0.5.1-beta-0 --- CHANGELOG.md | 13 +++++++++ nodes/blind-control.js | 17 +++++------- nodes/lib/dateTimeHelper.js | 54 +++++++++++++++++++++++++------------ package.json | 2 +- 4 files changed, 57 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28748288..d5829571 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # node-red-contrib-sun-position +#### 0.5.1-beta-0: BugFix and Maintenance Release + +- general + - fix for week number calculation when in daylight saving #65 + - if time output as object the week is now an extra object with properties + - iso *array* `[year, week]` + - week *number* week number + - year *number* full year + - even *boolean* is true if week is even +- blind control + - change logic of rule execution: From rules within Until rules will now considered. + - change should have no affect if rule setup is equal to the examples, that time restricted rules separated in first only until and afterwards only from rules + #### 0.5.0: mayor release for blind control - configuration diff --git a/nodes/blind-control.js b/nodes/blind-control.js index 61d4257b..63c12a05 100644 --- a/nodes/blind-control.js +++ b/nodes/blind-control.js @@ -781,29 +781,24 @@ module.exports = function (RED) { const rule = node.rules.data[i]; // node.debug('rule ' + rule.timeOp + ' - ' + (rule.timeOp !== cRuleFrom) + ' - ' + util.inspect(rule, {colors:true, compact:10, breakLength: Infinity })); if (rule.timeOp === cRuleFrom) { continue; } - const res = fktCheck(rule, r => (r >= nowNr)); - /* let res = null; + // const res = fktCheck(rule, r => (r >= nowNr)); + let res = null; if (rule.timeOp === cRuleFrom) { res = fktCheck(rule, r => (r <= nowNr)); } else { res = fktCheck(rule, r => (r >= nowNr)); - } */ + } if (res) { node.debug('1. ruleSel ' + util.inspect(res, { colors: true, compact: 10, breakLength: Infinity })); - /* if (Boolean(ruleSel) && res.timeOp === cRuleUntil) { - node.debug('break'); - // es gibt bereits eine treffende Regel - // nachfolgende BIS Regel wird nicht mehr ausgeführt - // nachfolgende VON Regeln werden ausgeführt (wenn sie zeitlich passen) - break; - } */ if (res.levelOp === cRuleMinOversteer) { ruleSelMin = res; } else if (res.levelOp === cRuleMaxOversteer) { ruleSelMax = res; } else { ruleSel = res; - break; + if (rule.timeOp !== cRuleFrom) { + break; + } } } } diff --git a/nodes/lib/dateTimeHelper.js b/nodes/lib/dateTimeHelper.js index b9d97f79..774b436b 100644 --- a/nodes/lib/dateTimeHelper.js +++ b/nodes/lib/dateTimeHelper.js @@ -289,23 +289,37 @@ function getSpecialDayOfMonth(year, month, dayName) { } /** - * get the week number for a a date + * For a given date, get the ISO week number + * + * Based on information at: + * + * http://www.merlyn.demon.co.uk/weekcalc.htm#WNR + * + * Algorithm is to find nearest thursday, it's year + * is the year of the week number. Then get weeks + * between that date and the first day of that year. + * + * Note that dates in one year can be weeks of previous + * or next year, overlap is up to 3 days. + * + * e.g. 2014/12/29 is Monday in week 1 of 2015 + * 2012/1/1 is Sunday in week 52 of 2011 + * * @param {Date} date date to get week number * @returns {Number} week number */ function getWeekNumber(date) { - const dt = new Date(date); - const target = new Date(dt.valueOf()); - const dayNumber = (dt.getUTCDay() + 6) % 7; - - target.setUTCDate(target.getUTCDate() - dayNumber + 3); - const firstThursday = target.valueOf(); - target.setUTCMonth(0, 1); - - if (target.getUTCDay() !== 4) { - target.setUTCMonth(0, 1 + ((4 - target.getUTCDay()) + 7) % 7); - } - return Math.ceil((firstThursday - target) / (7 * 24 * 3600 * 1000)) + 1; + // Copy date so don't modify original + date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())); + // Set to nearest Thursday: current date + 4 - current day number + // Make Sunday's day number 7 + date.setUTCDate(date.getUTCDate() + 4 - (date.getUTCDay()||7)); + // Get first day of year + const yearStart = new Date(Date.UTC(date.getUTCFullYear(),0,1)); + // Calculate full weeks to nearest Thursday + const weekNo = Math.ceil(( ( (date - yearStart) / 86400000) + 1)/7); + // Return array of year and week number + return [date.getUTCFullYear(), weekNo]; } /*******************************************************************************************************/ /* date-time functions */ @@ -833,7 +847,7 @@ const _dateFormat = (function () { tt: H < 12 ? 'am' : 'pm', T: H < 12 ? 'A' : 'P', TT: H < 12 ? 'AM' : 'PM', - ww: getWeekNumber(date), + ww: getWeekNumber(date)[1], Z: utc ? 'UTC' : /.*\s(.+)/.exec(date.toLocaleTimeString([], { timeZoneName: 'short' }))[1], z: utc ? '' : (String(date).match(/\b(?:GMT|UTC)(?:[-+]\d{4})?\b/g) || ['']).pop(), zz: utc ? '' : (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4), @@ -1082,13 +1096,14 @@ function getFormattedDateOut(date, format, utc, timeZoneOffset) { // eslint-disa + (offset === 0 ? 'Z' : (offset < 0 ? '+' : '-') + pad2(h) + ':' + pad2(m)); } case 19: // workweek - return getWeekNumber(date); + return getWeekNumber(date)[1]; case 20: // workweek even - return !Boolean(getWeekNumber(date) % 2); // eslint-disable-line no-extra-boolean-cast + return !(getWeekNumber(date)[1] % 2); // eslint-disable-line no-extra-boolean-cast } const now = new Date(); const delay = (date.getTime() - now.getTime()); + const week = getWeekNumber(date); return { date, ts: date.getTime(), @@ -1097,7 +1112,12 @@ function getFormattedDateOut(date, format, utc, timeZoneOffset) { // eslint-disa delay, delaySec: Math.round(delay / 1000), lc: now.getTime(), - week: getWeekNumber(date) + week: { + iso : week, + week : week[1], + year : week[0], + even : !(week[1] % 2) + } }; } // =================================================================== diff --git a/package.json b/package.json index 3d584bc3..cf3ee714 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-sun-position", - "version": "0.5.0", + "version": "0.5.1-beta-0", "description": "NodeRED nodes to get sun and moon position", "keywords": [ "node-red", From d2f06025caa44942a8909700a8e59286eeb4e60a Mon Sep 17 00:00:00 2001 From: Hypnos <12692680+Hypnos3@users.noreply.github.com> Date: Tue, 5 Nov 2019 23:17:56 +0100 Subject: [PATCH 2/8] fix for #66 if the blind not uses values between 0 and 1 --- nodes/blind-control.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nodes/blind-control.js b/nodes/blind-control.js index 63c12a05..765b5f34 100644 --- a/nodes/blind-control.js +++ b/nodes/blind-control.js @@ -265,7 +265,7 @@ module.exports = function (RED) { } else if (val > 99) { return node.blindData.levelTop; } - return (val / 100); + return posPrcToAbs_(node, val / 100); } throw new Error(`unknown value "${value}" of type "${type}"` ); } From 48371b252bcbaeac055c52e9985a1b62def0febf Mon Sep 17 00:00:00 2001 From: Hypnos <12692680+Hypnos3@users.noreply.github.com> Date: Tue, 5 Nov 2019 23:38:20 +0100 Subject: [PATCH 3/8] 0.5.1-beta-1 --- CHANGELOG.md | 2 + nodes/blind-control.html | 203 +++++++++++++++++++++++++++++-------- nodes/position-config.js | 4 +- nodes/static/htmlglobal.js | 4 +- package-lock.json | 2 +- package.json | 2 +- 6 files changed, 168 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5829571..f422bccd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - year *number* full year - even *boolean* is true if week is even - blind control + - fix for #66 if the blind not uses values between 0 and 1 + - enhanced output of the rules - change logic of rule execution: From rules within Until rules will now considered. - change should have no affect if rule setup is equal to the examples, that time restricted rules separated in first only until and afterwards only from rules diff --git a/nodes/blind-control.html b/nodes/blind-control.html index b6bd58ed..d01caba6 100644 --- a/nodes/blind-control.html +++ b/nodes/blind-control.html @@ -173,28 +173,86 @@ } if (t === 'pdsCalcData') { - return '{sun position}'; + return `"${node._('node-red-contrib-sun-position/position-config:common.types.suncalc')}"`; } if (t === 'pdsCalcPercent') { - return '{sun in sky percent}'; + return `"${node._('node-red-contrib-sun-position/position-config:common.types.suninsky')}"`; + // return '{sun in sky percent}'; } if (t === 'pdmCalcData') { - return '{moon position}'; + return `"${node._('node-red-contrib-sun-position/position-config:common.types.mooncalc')}"`; + // return '{moon position}'; } if (t === 'pdmPhase') { - return '{moon phase}'; + return `"${node._('node-red-contrib-sun-position/position-config:common.types.moonPhase')}"`; + // return '{moon phase}'; } if (t === 'pdsTime') { - const res = v.replace('astronomical', 'astro-').replace('nautical', 'naut-').replace('amateur', 'amat-').replace('blueHour', 'blueHr-').replace('goldenHour', 'goldHr-'); - return clipValueLength(res, l); + switch (v) { + case 'astronomicalDawn': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.astronomicalDawn'); + case 'amateurDawn': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.amateurDawn'); + case 'nauticalDawn': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.nauticalDawn'); + case 'blueHourDawnStart': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.blueHourDawnStart'); + case 'civilDawn': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.civilDawn'); + case 'blueHourDawnEnd': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.blueHourDawnEnd'); + case 'goldenHourDawnStart': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.goldenHourDawnStart'); + case 'sunrise': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.sunrise'); + case 'sunriseEnd': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.sunriseEnd'); + case 'goldenHourDawnEnd': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.goldenHourDawnEnd'); + case 'solarNoon': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.solarNoon'); + case 'goldenHourDuskStart': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.goldenHourDuskStart'); + case 'sunsetStart': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.sunsetStart'); + case 'sunset': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.sunset'); + case 'goldenHourDuskEnd': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.goldenHourDuskEnd'); + case 'blueHourDuskStart': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.blueHourDuskStart'); + case 'civilDusk': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.civilDusk'); + case 'blueHourDuskEnd': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.blueHourDuskEnd'); + case 'nauticalDusk': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.nauticalDusk'); + case 'amateurDusk': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.amateurDusk'); + case 'astronomicalDusk': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.astronomicalDusk'); + case 'nadir': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.nadir'); + default: + return v; + } + // const res = v.replace('astronomical', 'astro-').replace('nautical', 'naut-').replace('amateur', 'amat-').replace('blueHour', 'blueHr-').replace('goldenHour', 'goldHr-'); + // return clipValueLength(res, l); } if (t === 'pdmTime') { - return 'moon' + v; + switch (v) { + case 'rise': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.moonRise', 'rise'); + case 'set': + return node._('node-red-contrib-sun-position/position-config:common.typeOptions.moonSet', 'set'); + default: + return 'moon' + v; + } } if (t === 'msgPayload') { return 'msg.payload'; } @@ -210,10 +268,22 @@ return clipValueLength(v, l); } + /** + * get a time in millisecond as string of the format hh:mm, hh:mm:ss or hh:mm:ss.mss + * @param {number} s - milisecond + * @returns {string} time as string + */ + function msToTime(s) { + // Pad to 2 or 3 digits, default is 2 + const pad = (n, z = 2) => ('00' + n).slice(-z); + const sec = (s%6e4)/1000|0; + const msec = s%1000; + return pad(s/3.6e6|0) + ':' + pad((s%3.6e6)/6e4 | 0) + ((msec >0) ? (':' + pad(sec) +'.' + pad(msec, 3) ) : ((sec>0) ? ':' + pad(sec) : '')); + } /** * get a description of the rule rules * @param {object} data - a rule description - * @returns {steing} description of the rule + * @returns {string} description of the rule */ function getRuleDescription(node, selFields, data) { let result = ''; @@ -222,8 +292,7 @@ result += '
'; result += ' '; - - result += getValueLabel(node, data.validOperandAType,data.validOperandAValue); + result += '' + getValueLabel(node, data.validOperandAType,data.validOperandAValue) + ''; // result += node._('node-red-contrib-sun-position/position-config:common.comparatorDescription.' + data.validOperator); result += ' ' + data.validOperatorText; let operatorCount = 1; @@ -241,9 +310,9 @@ result += ' ' + getValueLabel(node, data.validOperandBType, data.validOperandBValue); } if (data.valid2LogOperator > 0 && data.valid2OperandAType !== 'none') { - result += ' ' + data.valid2LogOperatorText + ' '; + result += '
' + data.valid2LogOperatorText + ' '; - result += getValueLabel(node, data.valid2OperandAType,data.valid2OperandAValue); + result += '' + getValueLabel(node, data.valid2OperandAType,data.valid2OperandAValue) + ''; result += ' ' + data.valid2OperatorText; let operatorCount = 1; const fields = selFields.comparator; @@ -266,25 +335,60 @@ result += '
'; result += ' '; result += data.timeOpText; - result += ' ' + getValueLabel(node, data.timeType, data.timeValue); + result += ' ' + getValueLabel(node, data.timeType, data.timeValue) + ''; if (data.offsetType && data.offsetType !== 'none') { - result += ' offset ' + getValueLabel(node, data.offsetType, data.offsetValue); - result += ' * ' + data.multiplier/1000 + 's'; + if (data.offsetType === 'num') { + const osmillis = data.offsetValue * data.multiplier; + if (osmillis>0) { + result += ' + ' + msToTime(osmillis); + } else { + result += ' - ' +msToTime(osmillis * -1); + } + } else { + result += ' offset ' + getValueLabel(node, data.offsetType, data.offsetValue) + ''; + // result += ' * ' + data.multiplier/1000 + 's'; + } } if (data.timeMinType && data.timeMinType !== 'none') { - result += '
' + node._('blind-control.label.ruleTimeMin') + ' ' + getValueLabel(node, data.timeMinType, data.timeMinValue); + result += '
'; + result += node._('blind-control.label.ruleTimeMin'); + result += ' '; + result += getValueLabel(node, data.timeMinType, data.timeMinValue); + result += ''; if (data.offsetMinType && data.offsetMinType !== 'none') { - result += ' offset ' + getValueLabel(node, data.offsetMinType, data.offsetMinValue); - result += ' * ' + data.multiplierMin/1000 + 's'; + if (data.offsetMinType === 'num') { + const osmillis = data.offsetMinValue * data.multiplierMin; + if (osmillis>0) { + result += ' + ' + msToTime(osmillis); + } else { + result += ' - ' + msToTime(osmillis * -1); + } + } else { + result += ' offset ' + getValueLabel(node, data.offsetMinType, data.offsetMinValue); + // result += ' * ' + data.multiplierMin/1000 + 's'; + } } result += '
'; } if (data.timeMaxType && data.timeMaxType !== 'none') { - result += '
' + node._('blind-control.label.ruleTimeMax') + ' ' + getValueLabel(node, data.timeMaxType, data.timeMaxValue); + result += '
'; + result += node._('blind-control.label.ruleTimeMax'); + result += ' '; + result += getValueLabel(node, data.timeMaxType, data.timeMaxValue); + result += ''; if (data.offsetMaxType && data.offsetMaxType !== 'none') { - result += ' offset ' + getValueLabel(node, data.offsetMaxType, data.offsetMaxValue); - result += ' * ' + data.multiplierMax/1000 + 's'; + if (data.offsetMaxType === 'num') { + const osmillis = data.offsetMaxValue * data.multiplierMax; + if (osmillis>0) { + result += ' + ' + msToTime(osmillis); + } else { + result += ' - ' +msToTime(osmillis * -1); + } + } else { + result += ' offset ' + getValueLabel(node, data.offsetMaxType, data.offsetMaxValue); + // result += ' * ' + data.multiplierMax/1000 + 's'; + } } result += '
'; } @@ -302,6 +406,7 @@ } } else { result += data.levelOpText + ' ' + getValueLabel(node, data.levelType, data.levelValue); + // 2 out of 10 } } else { result += '-'; @@ -931,7 +1036,7 @@ data.levelOp = (Number(data.levelOp) || 0); data.conditional = ((data.validOperandAType !== 'none') ? 1 : 0); data.timeLimited = ((data.timeType !== 'none') ? 1 : 0); - data.timeData = (parseFloat($(this).find('.node-input-rule-time').attr('timedata')) || 0); + data.timeData = (parseFloat($(this).find('.node-input-rule-timeReg').attr('timedata')) || 0); data.timeOp = (data.timeLimited) ? (Number(data.timeOp) || 0) : -1; }); /** @@ -1372,25 +1477,25 @@ $dialogCond2BOperand.typedInput('width', '70%'); // #endregion dialogCond2 // #region dialogTimeReg - const $dialogTimeRegOperator = $dialog.find('#dlg-ip-blindctl-rule-timeA-operator'); + const $dialogTimeRegOperator = $dialog.find('#dlg-ip-blindctl-rule-timeReg-operator'); $dialogTimeRegOperator.append($('').val(0).text(node._('blind-control.label.ruleTimeUntil'))); $dialogTimeRegOperator.append($('').val(1).text(node._('blind-control.label.ruleTimeFrom'))); - const $dialogTimeRegInput = $dialog.find('#dlg-ip-blindctl-rule-timeA'); + const $dialogTimeRegInput = $dialog.find('#dlg-ip-blindctl-rule-timeReg'); $dialogTimeRegInput.typedInput({ default: types.Undefined.value, types: [types.Undefined, types.TimeEntered, types.TimeSun, types.TimeMoon, 'msg', 'flow', 'global', 'env', 'jsonata'] }); $dialogTimeRegInput.typedInput('width', '40%'); - const $dialogTimeRegOffset = $dialog.find('#dlg-ip-blindctl-rule-offset-timeA'); + const $dialogTimeRegOffset = $dialog.find('#dlg-ip-blindctl-rule-offset-timeReg'); $dialogTimeRegOffset.typedInput({ default: types.Undefined.value, types: [types.Undefined, 'num', 'msg', 'flow', 'global', 'env', 'jsonata'] }).change(() => { $dialogTimeRegInput.change(); }); $dialogTimeRegOffset.typedInput('width', '40%'); - const $dialogTimeRegMultiplier = $dialog.find('#dlg-ip-blindctl-rule-multiplier-timeA'); + const $dialogTimeRegMultiplier = $dialog.find('#dlg-ip-blindctl-rule-multiplier-timeReg'); appendOptions(node, $dialogTimeRegMultiplier, 'multiplier', data => (data.id > 0)); // #endregion dialogTimeReg // #region dialogTimeMin @@ -1446,10 +1551,11 @@ if (dialogDataOnLoading) { return; } const opType = $dialogTimeRegInput.typedInput('type'); if (opType === types.Undefined.value) { - $('#dialog-row-time').attr('title', 'N/A'); + $('#dialog-row-timeReg').attr('title', 'N/A'); $dialogTimeRegInput.attr('timedata', '0'); $dialogTimeRegOperator.hide(); - $('#dialog-row-offset-timeA').hide(); + $('#dialog-row-offset-timeReg').hide(); + $('#dialog-row-timeReg').attr('title', opType); $('#dialog-row-timeMin').hide(); $('#dialog-row-timeMax').hide(); @@ -1466,18 +1572,19 @@ return; } else if (opType === types.TimeSun.value || opType === types.TimeMoon.value) { $dialogTimeRegOperator.show(); - $('#dialog-row-offset-timeA').show(); + $('#dialog-row-offset-timeReg').show(); } else { $dialogTimeRegOperator.show(); - $('#dialog-row-offset-timeA').hide(); + $('#dialog-row-offset-timeReg').hide(); } getBackendData(d => { + // console.log('getBackendData of $dialogTimeRegInput ',d); if (d.value && d.value !== 'none') { const dv = new Date(d.value); - $('#dialog-row-time').attr('title', bdDateToTime(dv)); + $('#dialog-row-timeReg').attr('title', bdDateToTime(dv)); $dialogTimeRegInput.attr('timedata', dv.getTime()); } else { - $('#dialog-row-time').attr('title', d.value); + $('#dialog-row-timeReg').attr('title', d.value); $dialogTimeRegInput.attr('timedata', '0'); } }, { @@ -1492,6 +1599,7 @@ $dialogTimeMinInput.change(); $dialogTimeMaxInput.change(); }); + $dialogTimeMinInput.change(() => { if (dialogDataOnLoading) { return; } const opAType = $dialogTimeRegInput.typedInput('type'); @@ -1500,6 +1608,9 @@ const opType = $dialogTimeMinInput.typedInput('type'); if (opType === types.Undefined.value) { $('#dialog-row-offset-timeMin').hide(); + $('#dialog-row-timeMin').attr('title', opType); + $dialogTimeMinInput.attr('timedata', '0'); + return; } else if (opType === types.TimeSun.value || opType === types.TimeMoon.value) { $('#dialog-row-offset-timeMin').show(); } else { @@ -1508,10 +1619,10 @@ getBackendData(d => { if (d.value && d.value !== 'none') { const dv = new Date(d.value); - $('#dialog-row-time').attr('title', bdDateToTime(dv)); + $('#dialog-row-timeMin').attr('title', bdDateToTime(dv)); $dialogTimeMinInput.attr('timedata', dv.getTime()); } else { - $('#dialog-row-time').attr('title', d.value); + $('#dialog-row-timeMin').attr('title', d.value); $dialogTimeMinInput.attr('timedata', '0'); } }, { @@ -1525,6 +1636,7 @@ }); } }); + $dialogTimeMaxInput.change(() => { if (dialogDataOnLoading) { return; } const opAType = $dialogTimeRegInput.typedInput('type'); @@ -1533,6 +1645,9 @@ const opType = $dialogTimeMaxInput.typedInput('type'); if (opType === types.Undefined.value) { $('#dialog-row-offset-timeMax').hide(); + $('#dialog-row-timeMax').attr('title', opType); + $dialogTimeMaxInput.attr('timedata', '0'); + return; } else if (opType === types.TimeSun.value || opType === types.TimeMoon.value) { $('#dialog-row-offset-timeMax').show(); } else { @@ -1541,10 +1656,10 @@ getBackendData(d => { if (d.value && d.value !== 'none') { const dv = new Date(d.value); - $('#dialog-row-time').attr('title', bdDateToTime(dv)); + $('#dialog-row-timeMax').attr('title', bdDateToTime(dv)); $dialogTimeMaxInput.attr('timedata', dv.getTime()); } else { - $('#dialog-row-time').attr('title', d.value); + $('#dialog-row-timeMax').attr('title', d.value); $dialogTimeMaxInput.attr('timedata', '0'); } }, { @@ -2072,16 +2187,16 @@
-
- - - +
-
- - - +
diff --git a/nodes/position-config.js b/nodes/position-config.js index c5726493..3c53116f 100644 --- a/nodes/position-config.js +++ b/nodes/position-config.js @@ -1052,7 +1052,9 @@ module.exports = function (RED) { if (req.query.config && req.query.config !== '_ADD_') { const posConfig = RED.nodes.getNode(req.query.config); if (!posConfig) { - res.status(500).send(JSON.stringify({})); + res.status(500).send(JSON.stringify({ + error: 'can not find position config node "' +req.query.config+'" '+String(posConfig) + })); return; } let obj = {}; diff --git a/nodes/static/htmlglobal.js b/nodes/static/htmlglobal.js index 127f6f56..f85d5f39 100644 --- a/nodes/static/htmlglobal.js +++ b/nodes/static/htmlglobal.js @@ -908,7 +908,7 @@ function multiselect(node, parent, elementName, i18N, id) { // eslint-disable-li * @returns {*} object based on the request */ function getBackendData(result, data) { // eslint-disable-line no-unused-vars - // console.log('[IN getBackendData] ',data); // eslint-disable-line + console.log('[IN getBackendData] ',data); // eslint-disable-line let res = ''; if (!data || data.type === 'none' || data.type === '' || data.type === 'jsonata' || data.type === 'json' || data.type === 'bin') { res = data.type; @@ -919,7 +919,7 @@ function getBackendData(result, data) { // eslint-disable-line no-unused-vars } else if (data.type === 'msgPayload') { res = 'msg.payload'; } else if (data.type === 'PlT') { - res = 'msg.payload'; + res = 'msg.payload if msg.topic contains "' + data.value + '"'; } else if (data.type === 'msgTs') { res = 'msg.ts'; } else if (data.type === 'msgLC') { diff --git a/package-lock.json b/package-lock.json index d3c668d1..8444fede 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-sun-position", - "version": "0.5.0", + "version": "0.5.1-beta-1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index cf3ee714..1ce505eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-sun-position", - "version": "0.5.1-beta-0", + "version": "0.5.1-beta-1", "description": "NodeRED nodes to get sun and moon position", "keywords": [ "node-red", From 94d6283727a657b97d21c17ae316c3004c2b985f Mon Sep 17 00:00:00 2001 From: Hypnos <12692680+Hypnos3@users.noreply.github.com> Date: Wed, 6 Nov 2019 23:46:08 +0100 Subject: [PATCH 4/8] fix for #67 --- CHANGELOG.md | 1 + nodes/blind-control.html | 215 +++++++++++++++++-------- nodes/blind-control.js | 4 +- nodes/locales/de/blind-control.json | 5 +- nodes/locales/en-US/blind-control.json | 5 +- package-lock.json | 2 +- package.json | 2 +- 7 files changed, 157 insertions(+), 77 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f422bccd..f9792416 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - even *boolean* is true if week is even - blind control - fix for #66 if the blind not uses values between 0 and 1 + - fix for #67 mixed earliest and latest settings - enhanced output of the rules - change logic of rule execution: From rules within Until rules will now considered. - change should have no affect if rule setup is equal to the examples, that time restricted rules separated in first only until and afterwards only from rules diff --git a/nodes/blind-control.html b/nodes/blind-control.html index d01caba6..0363c957 100644 --- a/nodes/blind-control.html +++ b/nodes/blind-control.html @@ -280,12 +280,33 @@ const msec = s%1000; return pad(s/3.6e6|0) + ':' + pad((s%3.6e6)/6e4 | 0) + ((msec >0) ? (':' + pad(sec) +'.' + pad(msec, 3) ) : ((sec>0) ? ':' + pad(sec) : '')); } + + /** + * get the time offset text + */ + function _getOffsetText(node, t,v,m) { + let result = ''; + if (t && t !== 'none') { + if (t === 'num') { + const osmillis = v * m; + if (osmillis>0) { + result += ' + ' + msToTime(osmillis); + } else { + result += ' - ' +msToTime(osmillis * -1); + } + } else { + result += ' offset ' + getValueLabel(node, t, v) + ''; + // result += ' * ' + data.multiplier/1000 + 's'; + } + } + return result; + } /** * get a description of the rule rules * @param {object} data - a rule description * @returns {string} description of the rule */ - function getRuleDescription(node, selFields, data) { + function getRuleDescription(node, selFields, data, enh) { let result = ''; try { if (data.validOperandAType && data.validOperandAType !== 'none') { @@ -336,18 +357,9 @@ result += ' '; result += data.timeOpText; result += ' ' + getValueLabel(node, data.timeType, data.timeValue) + ''; - if (data.offsetType && data.offsetType !== 'none') { - if (data.offsetType === 'num') { - const osmillis = data.offsetValue * data.multiplier; - if (osmillis>0) { - result += ' + ' + msToTime(osmillis); - } else { - result += ' - ' +msToTime(osmillis * -1); - } - } else { - result += ' offset ' + getValueLabel(node, data.offsetType, data.offsetValue) + ''; - // result += ' * ' + data.multiplier/1000 + 's'; - } + result += _getOffsetText(node, data.offsetType, data.offsetValue, data.multiplier); + if (enh && enh.timeReg) { + result += '  ' + enh.timeReg.text + ''; } if (data.timeMinType && data.timeMinType !== 'none') { @@ -356,18 +368,9 @@ result += ' '; result += getValueLabel(node, data.timeMinType, data.timeMinValue); result += ''; - if (data.offsetMinType && data.offsetMinType !== 'none') { - if (data.offsetMinType === 'num') { - const osmillis = data.offsetMinValue * data.multiplierMin; - if (osmillis>0) { - result += ' + ' + msToTime(osmillis); - } else { - result += ' - ' + msToTime(osmillis * -1); - } - } else { - result += ' offset ' + getValueLabel(node, data.offsetMinType, data.offsetMinValue); - // result += ' * ' + data.multiplierMin/1000 + 's'; - } + result += _getOffsetText(node, data.offsetMinType, data.offsetMinValue, data.multiplierMin); + if (enh && enh.timeMin) { + result += '  ' + enh.timeMin.text + ''; } result += '
'; } @@ -377,18 +380,9 @@ result += ' '; result += getValueLabel(node, data.timeMaxType, data.timeMaxValue); result += ''; - if (data.offsetMaxType && data.offsetMaxType !== 'none') { - if (data.offsetMaxType === 'num') { - const osmillis = data.offsetMaxValue * data.multiplierMax; - if (osmillis>0) { - result += ' + ' + msToTime(osmillis); - } else { - result += ' - ' +msToTime(osmillis * -1); - } - } else { - result += ' offset ' + getValueLabel(node, data.offsetMaxType, data.offsetMaxValue); - // result += ' * ' + data.multiplierMax/1000 + 's'; - } + result += _getOffsetText(node, data.offsetMaxType, data.offsetMaxValue, data.multiplierMax); + if (enh && enh.timeMax) { + result += '  ' + enh.timeMin.text + ''; } result += '
'; } @@ -924,7 +918,7 @@ } $('#node-input-rule-container').css('min-height', '40px').css('min-width', '300px').editableList({ - addItem(containerRow, containerIndex, data) { + addItem($containerRow, containerIndex, data) { if (data === {}) { data.description = 'please edit rule'; data.name = 'empty'; @@ -963,9 +957,9 @@ } data.levelOpText = data.levelOpText || node._('blind-control.label.ruleLevelAbs'); - containerRow.data('ruleData', JSON.stringify(data)); - containerRow.css({ overflow: 'hidden'}); // , whiteSpace: 'nowrap' - const $row0 = $('
').appendTo(containerRow); + $containerRow.data('ruleData', JSON.stringify(data)); + $containerRow.css({ overflow: 'hidden'}); // , whiteSpace: 'nowrap' + const $row0 = $('
').appendTo($containerRow); const $div = $('
', { class: 'blind-rule-mainblock' }).appendTo($row0); @@ -989,7 +983,7 @@ }).append('').appendTo($row0); // $btn.button(); $btn.click(() => { - _dialogLoadData(containerIndex, containerRow); + _dialogLoadData(containerIndex, $containerRow); }); }, addButton: false, @@ -1423,17 +1417,22 @@ Ok() { _dialogSaveData(); $dialog.dialog( 'close' ); + $dialogDataRow = null; + dialogDataIndex = -1; }, Cancel() { $dialog.dialog( 'close' ); + $dialogDataRow = null; + dialogDataIndex = -1; } } }); const $dialogName = $dialog.find('#dlg-ip-blindctl-rule-name'); - let dialogData = null; + let $dialogDataRow = null; let dialogDataOnLoading = false; let dialogDataIndex = -1; + const dialogAddData = {}; /** * Build the dialog */ @@ -1551,8 +1550,13 @@ if (dialogDataOnLoading) { return; } const opType = $dialogTimeRegInput.typedInput('type'); if (opType === types.Undefined.value) { - $('#dialog-row-timeReg').attr('title', 'N/A'); - $dialogTimeRegInput.attr('timedata', '0'); + dialogAddData.timeReg = { + ts : 0, + data : null, + text : 'N/A' + }; + $('#dialog-row-timeReg').attr('title', dialogAddData.timeReg.text); + $dialogTimeRegInput.attr('timedata', dialogAddData.timeReg.ts); $dialogTimeRegOperator.hide(); $('#dialog-row-offset-timeReg').hide(); $('#dialog-row-timeReg').attr('title', opType); @@ -1569,6 +1573,7 @@ if ($dialogTimeMaxInput.typedInput('type') !== types.Undefined.value) { $dialogTimeMaxInput.typedInput('type', types.Undefined.value); } + _dialogGenHelpText(); return; } else if (opType === types.TimeSun.value || opType === types.TimeMoon.value) { $dialogTimeRegOperator.show(); @@ -1581,12 +1586,21 @@ // console.log('getBackendData of $dialogTimeRegInput ',d); if (d.value && d.value !== 'none') { const dv = new Date(d.value); - $('#dialog-row-timeReg').attr('title', bdDateToTime(dv)); - $dialogTimeRegInput.attr('timedata', dv.getTime()); + dialogAddData.timeReg = { + ts : dv.getTime(), + data : d, + text : bdDateToTime(dv) + }; } else { - $('#dialog-row-timeReg').attr('title', d.value); - $dialogTimeRegInput.attr('timedata', '0'); + dialogAddData.timeReg = { + ts : 0, + data : null, + text : d.value + }; } + $('#dialog-row-timeReg').attr('title', dialogAddData.timeReg.text); + $dialogTimeRegInput.attr('timedata', dialogAddData.timeReg.ts); + _dialogGenHelpText(); }, { kind: 'getTimeData', config : $nodeConfig.val(), @@ -1608,8 +1622,14 @@ const opType = $dialogTimeMinInput.typedInput('type'); if (opType === types.Undefined.value) { $('#dialog-row-offset-timeMin').hide(); - $('#dialog-row-timeMin').attr('title', opType); - $dialogTimeMinInput.attr('timedata', '0'); + dialogAddData.timeMin = { + ts : 0, + data : null, + text : 'N/A' + }; + $('#dialog-row-timeMin').attr('title', dialogAddData.timeMin.text); + $dialogTimeMinInput.attr('timedata', dialogAddData.timeMin.ts); + _dialogGenHelpText(); return; } else if (opType === types.TimeSun.value || opType === types.TimeMoon.value) { $('#dialog-row-offset-timeMin').show(); @@ -1619,12 +1639,21 @@ getBackendData(d => { if (d.value && d.value !== 'none') { const dv = new Date(d.value); - $('#dialog-row-timeMin').attr('title', bdDateToTime(dv)); - $dialogTimeMinInput.attr('timedata', dv.getTime()); + dialogAddData.timeMin = { + ts : dv.getTime(), + data : d, + text : bdDateToTime(dv) + }; } else { - $('#dialog-row-timeMin').attr('title', d.value); - $dialogTimeMinInput.attr('timedata', '0'); + dialogAddData.timeMin = { + ts : 0, + data : null, + text : d.value + }; } + $('#dialog-row-timeMin').attr('title', dialogAddData.timeMin.text); + $dialogTimeMinInput.attr('timedata', dialogAddData.timeMin.ts); + _dialogGenHelpText(); }, { kind: 'getTimeData', config: $nodeConfig.val(), @@ -1645,8 +1674,14 @@ const opType = $dialogTimeMaxInput.typedInput('type'); if (opType === types.Undefined.value) { $('#dialog-row-offset-timeMax').hide(); - $('#dialog-row-timeMax').attr('title', opType); - $dialogTimeMaxInput.attr('timedata', '0'); + dialogAddData.timeMax = { + ts : 0, + data : null, + text : 'N/A' + }; + $('#dialog-row-timeMax').attr('title', dialogAddData.timeMax.text); + $dialogTimeMaxInput.attr('timedata', dialogAddData.timeMax.ts); + _dialogGenHelpText(); return; } else if (opType === types.TimeSun.value || opType === types.TimeMoon.value) { $('#dialog-row-offset-timeMax').show(); @@ -1656,12 +1691,21 @@ getBackendData(d => { if (d.value && d.value !== 'none') { const dv = new Date(d.value); - $('#dialog-row-timeMax').attr('title', bdDateToTime(dv)); - $dialogTimeMaxInput.attr('timedata', dv.getTime()); + dialogAddData.timeMax = { + ts : dv.getTime(), + data : d, + text : bdDateToTime(dv) + }; } else { - $('#dialog-row-timeMax').attr('title', d.value); - $dialogTimeMaxInput.attr('timedata', '0'); + dialogAddData.timeMax = { + ts : 0, + data : null, + text : d.value + }; } + $('#dialog-row-timeMax').attr('title', dialogAddData.timeMax.text); + $dialogTimeMaxInput.attr('timedata', dialogAddData.timeMax.ts); + _dialogGenHelpText(); }, { kind: 'getTimeData', config: $nodeConfig.val(), @@ -1713,10 +1757,12 @@ } $dialogCondBOperand.change(); $dialogCond2AOperand.change(); + _dialogGenHelpText(); }); $dialogCondAOperator.change(() => { $dialogCondAOperand.change(); }); $dialogCond2AOperand.change(() => { + if (dialogDataOnLoading) { return; } const op2 = parseInt($dialogCond2LogOperator.val()); if (isNaN(op2) || op2 === 0) { $dialogCond2AOperator.val(selFields.comparator[0].id); @@ -1759,6 +1805,7 @@ } } $dialogCond2BOperand.change(); + _dialogGenHelpText(); }); $dialogCond2LogOperator.change(() => { $dialogCond2AOperand.change(); }); $dialogCond2AOperator.change(() => { $dialogCond2AOperand.change(); }); @@ -1779,14 +1826,29 @@ } // $field.typedInput('type', type); } + + /** + * generates the help text of the dialog + */ + function _dialogGenHelpText() { + $('#dlg-txt-blindctl-rule-descr').html(''); + if (dialogAddData.timeout) { + clearTimeout(dialogAddData.timeout); + dialogAddData.timeout = null; + } + dialogAddData.timeout = setTimeout(() => { + dialogAddData.timeout = null; + $('#dlg-txt-blindctl-rule-descr').html(getRuleDescription(node, selFields, _dialogGetData(), dialogAddData)); + },1000); + } /** * load the data from the rule */ - function _dialogLoadData(containerIndex, containerRow) { + function _dialogLoadData(containerIndex, $containerRow) { try { - dialogData = containerRow; + $dialogDataRow = $containerRow; dialogDataIndex = containerIndex; - const data = JSON.parse(dialogData.data('ruleData')); + const data = JSON.parse($dialogDataRow.data('ruleData')); $dialogName.val(data.name); dialogDataOnLoading = true; @@ -1816,6 +1878,7 @@ setTI($dialogLevel, data.levelValue, data.levelType); $dialogLevel.typedInput('value',data.levelValue); $dialogLevel.typedInput('type',data.levelType); + _dialogGenHelpText(); dialogDataOnLoading = false; $dialogCondAOperand.change(); @@ -1829,10 +1892,10 @@ } /** - * save the data of the rule back + * Get the data object for a rule */ - function _dialogSaveData() { - const data = { + function _dialogGetData() { + return { index: dialogDataIndex, name:$dialogName.val(), @@ -1877,8 +1940,14 @@ valid2OperandBValue: $dialogCond2BOperand.typedInput('value'), valid2OperandBType: $dialogCond2BOperand.typedInput('type') }; + } + /** + * save the data of the rule back + */ + function _dialogSaveData() { + const data = _dialogGetData(); data.description = getRuleDescription(node, selFields, data); - dialogData.data('ruleData', JSON.stringify(data)); + $dialogDataRow.data('ruleData', JSON.stringify(data)); $('#rule-name-'+dialogDataIndex).text(data.name || 'rule ' + (dialogDataIndex + 1)); $('#rule-description-'+dialogDataIndex).html(data.description); resizeContainer(); @@ -2227,6 +2296,10 @@
+
+ +
+
\ No newline at end of file + }); + })(); \ No newline at end of file diff --git a/nodes/time-inject.html b/nodes/time-inject.html index fd622a60..518ff031 100644 --- a/nodes/time-inject.html +++ b/nodes/time-inject.html @@ -353,1481 +353,1560 @@ \ No newline at end of file + }); + })(); \ No newline at end of file diff --git a/nodes/time-span.html b/nodes/time-span.html index 7092d725..89a8acdd 100644 --- a/nodes/time-span.html +++ b/nodes/time-span.html @@ -153,780 +153,843 @@ + }); + })(); diff --git a/nodes/within-time-switch.html b/nodes/within-time-switch.html index cdc1911a..22f710e8 100644 --- a/nodes/within-time-switch.html +++ b/nodes/within-time-switch.html @@ -164,790 +164,781 @@ \ No newline at end of file + }) + .fail((_jqxhr, settings, exception) => { + console.log("failed to load htmlglobal.js"); // eslint-disable-line + console.log(exception); // eslint-disable-line + console.log(exception.stack); // eslint-disable-line + }); + }, + oneditsave() { + this.propertyStartType = $('#node-input-propertyStart').typedInput('type'); + this.propertyEndType = $('#node-input-propertyEnd').typedInput('type'); + this.startTimeType = $('#node-input-startTime').typedInput('type'); + this.endTimeType = $('#node-input-endTime').typedInput('type'); + this.startTimeAltType = $('#node-input-startTimeAlt').typedInput('type'); + this.endTimeAltType = $('#node-input-endTimeAlt').typedInput('type'); + } + }); + })(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4bcbf201..1d65f892 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-sun-position", - "version": "0.5.1-beta-2", + "version": "0.5.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4d075e11..efab54d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-sun-position", - "version": "0.5.1-beta-2", + "version": "0.5.1", "description": "NodeRED nodes to get sun and moon position", "keywords": [ "node-red",