From b6132518675d889b4755b979a32deea515c938e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20H=C3=B6hn?= Date: Fri, 25 Aug 2023 23:52:16 +0200 Subject: [PATCH 1/7] [blockly] support Quantity in more math blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Höhn --- .../assets/definitions/blockly/blocks-math.js | 142 ++++++++++++++++++ .../config/controls/blockly-editor.vue | 12 ++ 2 files changed, 154 insertions(+) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js index 0756241d4b..813c2a50e3 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js @@ -162,4 +162,146 @@ export default function (f7, isGraalJs) { } return [code, 0] } + + Blockly.Blocks['math_single'] = { + init: function () { + const block = this + const dropDown = new Blockly.FieldDropdown([ + ['square root', 'ROOT'], + ['absolute', 'ABS'], + ['-', 'NEG'], + ['n', 'LN'], + ['log10', 'LOG10'], + ['e^', 'EXP'], + ['10^', 'POW10'] + ]) + this.appendValueInput('NUM') + .setCheck(['Number', 'oh_quantity']) + .appendField(dropDown, 'OP') + + this.setColour('%{BKY_MATH_HUE}') + this.setInputsInline(false) + let thisBlock = this + this.setTooltip(function () { + const operand = thisBlock.getFieldValue('OP') + switch (operand) { + case 'ROOT': return 'Return the square root of the input' + case 'ABS': return 'Return the absolute value of the input' + case 'NEG': return 'Return the negation of the input' + case 'LN': return 'Return the logarithm of the input' + case 'LOG10': return 'Return the 10 logarithm of the input' + case 'EXP': return 'Return e to the power of the input' + case 'POW10': return 'Return 10 to the power of the input' + } + }) + this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-math.html#functions') + this.setOutput(true, null) + } + } + + javascriptGenerator['math_single'] = function (block) { + const inputType = blockGetCheckedInputType(block, 'NUM') + const math_number_input = javascriptGenerator.valueToCode(block, 'NUM', javascriptGenerator.ORDER_FUNCTION_CALL) + let math_number = math_number_input + if (inputType === 'oh_quantity') { + math_number = math_number_input + '.float' + } + const operand = block.getFieldValue('OP') + + let code = '' + + let method = '' + switch (operand) { + case 'ROOT': + method = `Math.sqrt(${math_number})` + break + case 'ABS': + method = `Math.abs(${math_number})` + break + case 'NEG': + method = `-${math_number}` + break + case 'LN': + method = `Math.log(${math_number})` + break + case 'LOG10': + method = `Math.log(${math_number}) / Math.log(10)` + break + case 'EXP': + method = `Math.exp(${math_number})` + break + case 'POW10': + method = `Math.pow(10,${math_number})` + break + } + code = `${method}` + + if (inputType === 'oh_quantity') { + code = `Quantity((${code}).toString() + ' ' + ${math_number_input}.symbol)` + } + return [code, javascriptGenerator.ORDER_FUNCTION_CALL] + } + + Blockly.Blocks['oh_math_minmax'] = { + init: function () { + const block = this + const dropDown = new Blockly.FieldDropdown([ + ['minimum of', 'min'], + ['maximum of', 'max'] + ]) + this.appendDummyInput() + .appendField(dropDown, 'OP') + this.appendValueInput('NUM1') + .setCheck(['Number', 'oh_quantity']) + this.appendValueInput('NUM2') + .appendField(' and ') + .setCheck(['Number', 'oh_quantity']) + + this.setColour('%{BKY_MATH_HUE}') + this.setInputsInline(true) + let thisBlock = this + this.setTooltip(function () { + const operand = thisBlock.getFieldValue('OP') + switch (operand) { + case 'min': return 'Return the mimimum of both inputs' + case 'max': return 'Return the maximum of both inputs' + } + }) + this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-math.html#minmax') + this.setOutput(true, null) + } + } + + javascriptGenerator['oh_math_minmax'] = function (block) { + const inputType1 = blockGetCheckedInputType(block, 'NUM1') + const inputType2 = blockGetCheckedInputType(block, 'NUM2') + let math_number_input1 = javascriptGenerator.valueToCode(block, 'NUM1', javascriptGenerator.ORDER_FUNCTION_CALL) + let math_number_input2 = javascriptGenerator.valueToCode(block, 'NUM2', javascriptGenerator.ORDER_FUNCTION_CALL) + if (inputType1 !== 'oh_quantity' && inputType2 === 'oh_quantity') { + math_number_input2 = `${math_number_input2}.float` + } + if (inputType1 === 'oh_quantity' && inputType2 !== 'oh_quantity') { + math_number_input1 = `${math_number_input1}.float` + } + const operand = block.getFieldValue('OP') + + let code = '' + switch (operand) { + case 'min': + code = `Math.min(${math_number_input1},${math_number_input2})` + if (inputType1 === 'oh_quantity' && inputType2 === 'oh_quantity') { + code = `(${math_number_input1}.lessThan(${math_number_input2})) ? ${math_number_input1} : ${math_number_input2}` + } + break + + case 'max': + code = `Math.max(${math_number_input1},${math_number_input2})` + if (inputType1 === 'oh_quantity' && inputType2 === 'oh_quantity') { + code = `(${math_number_input1}.greaterThan(${math_number_input2})) ? ${math_number_input1} : ${math_number_input2}` + } + break + } + + return [code, javascriptGenerator.ORDER_FUNCTION_CALL] + } } diff --git a/bundles/org.openhab.ui/web/src/components/config/controls/blockly-editor.vue b/bundles/org.openhab.ui/web/src/components/config/controls/blockly-editor.vue index 1d28e61558..4db677bae7 100644 --- a/bundles/org.openhab.ui/web/src/components/config/controls/blockly-editor.vue +++ b/bundles/org.openhab.ui/web/src/components/config/controls/blockly-editor.vue @@ -116,6 +116,18 @@ + + + + 3 + + + + + 4 + + + From 3a1f22d2d55b5e1f7ea0d9925d2e86830959ae18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20H=C3=B6hn?= Date: Sat, 23 Sep 2023 09:35:45 +0200 Subject: [PATCH 2/7] minmax require equal operands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Höhn --- .../assets/definitions/blockly/blocks-math.js | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js index 813c2a50e3..f686cf5857 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js @@ -138,7 +138,7 @@ export default function (f7, isGraalJs) { const decimals = javascriptGenerator.valueToCode(block, 'DECIMALS', javascriptGenerator.ORDER_NONE) const operand = block.getFieldValue('op') - let code = '' + let code if (operand !== 'toFixed') { let method = '' switch (operand) { @@ -165,7 +165,6 @@ export default function (f7, isGraalJs) { Blockly.Blocks['math_single'] = { init: function () { - const block = this const dropDown = new Blockly.FieldDropdown([ ['square root', 'ROOT'], ['absolute', 'ABS'], @@ -208,8 +207,6 @@ export default function (f7, isGraalJs) { } const operand = block.getFieldValue('OP') - let code = '' - let method = '' switch (operand) { case 'ROOT': @@ -234,7 +231,8 @@ export default function (f7, isGraalJs) { method = `Math.pow(10,${math_number})` break } - code = `${method}` + + let code = `${method}` if (inputType === 'oh_quantity') { code = `Quantity((${code}).toString() + ' ' + ${math_number_input}.symbol)` @@ -244,7 +242,6 @@ export default function (f7, isGraalJs) { Blockly.Blocks['oh_math_minmax'] = { init: function () { - const block = this const dropDown = new Blockly.FieldDropdown([ ['minimum of', 'min'], ['maximum of', 'max'] @@ -277,14 +274,13 @@ export default function (f7, isGraalJs) { const inputType2 = blockGetCheckedInputType(block, 'NUM2') let math_number_input1 = javascriptGenerator.valueToCode(block, 'NUM1', javascriptGenerator.ORDER_FUNCTION_CALL) let math_number_input2 = javascriptGenerator.valueToCode(block, 'NUM2', javascriptGenerator.ORDER_FUNCTION_CALL) - if (inputType1 !== 'oh_quantity' && inputType2 === 'oh_quantity') { - math_number_input2 = `${math_number_input2}.float` - } - if (inputType1 === 'oh_quantity' && inputType2 !== 'oh_quantity') { - math_number_input1 = `${math_number_input1}.float` - } + const operand = block.getFieldValue('OP') + if (inputType1 !== inputType2) { + throw new Error(`both operand types need to be equal for ${operand.toUpperCase()}-block (${math_number_input1} -> ${inputType1},${math_number_input2} -> ${inputType2})`) + } + let code = '' switch (operand) { case 'min': From d857020b65370243eb13462646f574e5080b0cba Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Mon, 18 Sep 2023 20:53:13 +0200 Subject: [PATCH 3/7] (Code) Improvements Signed-off-by: Florian Hotze --- .../assets/definitions/blockly/blocks-math.js | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js index f686cf5857..0ef55fdddb 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js @@ -169,7 +169,7 @@ export default function (f7, isGraalJs) { ['square root', 'ROOT'], ['absolute', 'ABS'], ['-', 'NEG'], - ['n', 'LN'], + ['ln', 'LN'], ['log10', 'LOG10'], ['e^', 'EXP'], ['10^', 'POW10'] @@ -187,14 +187,14 @@ export default function (f7, isGraalJs) { case 'ROOT': return 'Return the square root of the input' case 'ABS': return 'Return the absolute value of the input' case 'NEG': return 'Return the negation of the input' - case 'LN': return 'Return the logarithm of the input' - case 'LOG10': return 'Return the 10 logarithm of the input' + case 'LN': return 'Return the natural (base e) logarithm of the input' + case 'LOG10': return 'Return the base 10 logarithm of the input' case 'EXP': return 'Return e to the power of the input' case 'POW10': return 'Return 10 to the power of the input' } }) this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-math.html#functions') - this.setOutput(true, null) + this.setOutput(true, 'Number') } } @@ -222,7 +222,7 @@ export default function (f7, isGraalJs) { method = `Math.log(${math_number})` break case 'LOG10': - method = `Math.log(${math_number}) / Math.log(10)` + method = `Math.log10(${math_number})` break case 'EXP': method = `Math.exp(${math_number})` @@ -272,29 +272,24 @@ export default function (f7, isGraalJs) { javascriptGenerator['oh_math_minmax'] = function (block) { const inputType1 = blockGetCheckedInputType(block, 'NUM1') const inputType2 = blockGetCheckedInputType(block, 'NUM2') - let math_number_input1 = javascriptGenerator.valueToCode(block, 'NUM1', javascriptGenerator.ORDER_FUNCTION_CALL) - let math_number_input2 = javascriptGenerator.valueToCode(block, 'NUM2', javascriptGenerator.ORDER_FUNCTION_CALL) + const math_number_input1 = javascriptGenerator.valueToCode(block, 'NUM1', javascriptGenerator.ORDER_FUNCTION_CALL) + const math_number_input2 = javascriptGenerator.valueToCode(block, 'NUM2', javascriptGenerator.ORDER_FUNCTION_CALL) const operand = block.getFieldValue('OP') if (inputType1 !== inputType2) { - throw new Error(`both operand types need to be equal for ${operand.toUpperCase()}-block (${math_number_input1} -> ${inputType1},${math_number_input2} -> ${inputType2})`) + throw new Error(`Both operand types need to be equal for ${operand.toUpperCase()}-block (${math_number_input1} -> ${inputType1}, ${math_number_input2} -> ${inputType2})`) } let code = '' - switch (operand) { - case 'min': - code = `Math.min(${math_number_input1},${math_number_input2})` - if (inputType1 === 'oh_quantity' && inputType2 === 'oh_quantity') { - code = `(${math_number_input1}.lessThan(${math_number_input2})) ? ${math_number_input1} : ${math_number_input2}` - } - break - case 'max': - code = `Math.max(${math_number_input1},${math_number_input2})` - if (inputType1 === 'oh_quantity' && inputType2 === 'oh_quantity') { - code = `(${math_number_input1}.greaterThan(${math_number_input2})) ? ${math_number_input1} : ${math_number_input2}` - } + switch (inputType1) { + case 'oh_quantity': + const op = (operand === 'min') ? 'lessThan' : 'greaterThan' + code = `(${math_number_input1}.${op}(${math_number_input2})) ? ${math_number_input1} : ${math_number_input2}` + break + default: + code = `Math.${operand}(${math_number_input1},${math_number_input2})` break } From cc26dbf3b5cf8541d631c2533554bc90e24746e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20H=C3=B6hn?= Date: Sat, 23 Sep 2023 14:58:38 +0200 Subject: [PATCH 4/7] support var type detection for min/max MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Höhn --- .../assets/definitions/blockly/blocks-math.js | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js index 0ef55fdddb..65570842a5 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js @@ -270,20 +270,32 @@ export default function (f7, isGraalJs) { } javascriptGenerator['oh_math_minmax'] = function (block) { - const inputType1 = blockGetCheckedInputType(block, 'NUM1') - const inputType2 = blockGetCheckedInputType(block, 'NUM2') const math_number_input1 = javascriptGenerator.valueToCode(block, 'NUM1', javascriptGenerator.ORDER_FUNCTION_CALL) const math_number_input2 = javascriptGenerator.valueToCode(block, 'NUM2', javascriptGenerator.ORDER_FUNCTION_CALL) + let inputType1 = blockGetCheckedInputType(block, 'NUM1') + let inputType2 = blockGetCheckedInputType(block, 'NUM2') + + /* + * When dealing with variables we need to find out best what we are dealing with to generate the right code + * if after detection still both types are different, we will throw an exception, but only of not a var is involved! + * if we don't know we will get back '' (=var) as the type and if both types are vars we need to assume the vars WILL contain a Number + * if only one of the types is a var, then we base the code generation on the other given input type + */ + inputType1 = detectVarQuantityNumberType(inputType1, math_number_input1) + inputType2 = detectVarQuantityNumberType(inputType2, math_number_input2) + const operand = block.getFieldValue('OP') + const containsOneVar = (inputType1 === '' && inputType2 !== '') || (inputType1 !== '' && inputType2 === '') - if (inputType1 !== inputType2) { + if (inputType1 !== inputType2 && !containsOneVar) { throw new Error(`Both operand types need to be equal for ${operand.toUpperCase()}-block (${math_number_input1} -> ${inputType1}, ${math_number_input2} -> ${inputType2})`) } + const leadType = (!containsOneVar) ? inputType1 : ((inputType1 === '') ? inputType2 : inputType1) let code = '' - switch (inputType1) { + switch (leadType) { case 'oh_quantity': const op = (operand === 'min') ? 'lessThan' : 'greaterThan' code = `(${math_number_input1}.${op}(${math_number_input2})) ? ${math_number_input1} : ${math_number_input2}` @@ -295,4 +307,18 @@ export default function (f7, isGraalJs) { return [code, javascriptGenerator.ORDER_FUNCTION_CALL] } + + /* + * let's deal with variables and try to do our best + * if the type is either Number or Quantity, then we don't mind + * only if the type is empty then we try to detect the type + * if the content of the block contains the word "Quantity", then type is oh_quantity + * if the content of the block otherwise contains a number, then the type is Number + */ + function detectVarQuantityNumberType (inputType, math_number_input) { + if (inputType !== '') return inputType + if (math_number_input.includes('Quantity')) return 'oh_quantity' + if (!isNaN(math_number_input)) return 'Number' + return '' + } } From 59c576d9eb8466802800cab5421478a6456e5afb Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Sat, 23 Sep 2023 18:21:43 +0200 Subject: [PATCH 5/7] Code improvements Signed-off-by: Florian Hotze --- .../assets/definitions/blockly/blocks-math.js | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js index 65570842a5..042c3a1c5c 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js @@ -270,29 +270,33 @@ export default function (f7, isGraalJs) { } javascriptGenerator['oh_math_minmax'] = function (block) { + const operand = block.getFieldValue('OP') + const math_number_input1 = javascriptGenerator.valueToCode(block, 'NUM1', javascriptGenerator.ORDER_FUNCTION_CALL) const math_number_input2 = javascriptGenerator.valueToCode(block, 'NUM2', javascriptGenerator.ORDER_FUNCTION_CALL) - let inputType1 = blockGetCheckedInputType(block, 'NUM1') - let inputType2 = blockGetCheckedInputType(block, 'NUM2') - /* - * When dealing with variables we need to find out best what we are dealing with to generate the right code - * if after detection still both types are different, we will throw an exception, but only of not a var is involved! - * if we don't know we will get back '' (=var) as the type and if both types are vars we need to assume the vars WILL contain a Number - * if only one of the types is a var, then we base the code generation on the other given input type + When dealing with variables, Blockly does not provide type information (type is ""). + In this case, we fall back to checking whether the actual input contains "Quantity" or is a number. */ - inputType1 = detectVarQuantityNumberType(inputType1, math_number_input1) - inputType2 = detectVarQuantityNumberType(inputType2, math_number_input2) + const inputType1 = blockGetCheckedInputType(block, 'NUM1') || getVariableType(math_number_input1) + const inputType2 = blockGetCheckedInputType(block, 'NUM2') || getVariableType(math_number_input2) - const operand = block.getFieldValue('OP') + /* + If exactly one of the two inputs is a variable, assume it has the same type as the other input. + In case both inputs are vars, assume they are numbers. + */ const containsOneVar = (inputType1 === '' && inputType2 !== '') || (inputType1 !== '' && inputType2 === '') + /* + If both inputs are not the same type and none of them is a variable, throw an Error on code generation. + */ if (inputType1 !== inputType2 && !containsOneVar) { throw new Error(`Both operand types need to be equal for ${operand.toUpperCase()}-block (${math_number_input1} -> ${inputType1}, ${math_number_input2} -> ${inputType2})`) } - const leadType = (!containsOneVar) ? inputType1 : ((inputType1 === '') ? inputType2 : inputType1) + const leadType = inputType1 || inputType1 + let code = '' switch (leadType) { @@ -315,8 +319,7 @@ export default function (f7, isGraalJs) { * if the content of the block contains the word "Quantity", then type is oh_quantity * if the content of the block otherwise contains a number, then the type is Number */ - function detectVarQuantityNumberType (inputType, math_number_input) { - if (inputType !== '') return inputType + function getVariableType (math_number_input) { if (math_number_input.includes('Quantity')) return 'oh_quantity' if (!isNaN(math_number_input)) return 'Number' return '' From 61390f52f66ba2887e6f0906287265615910f8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20H=C3=B6hn?= Date: Sat, 30 Sep 2023 17:46:44 +0200 Subject: [PATCH 6/7] set output type for minmax block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Höhn --- .../assets/definitions/blockly/blocks-math.js | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js index 042c3a1c5c..a9e7f98b46 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js @@ -264,23 +264,37 @@ export default function (f7, isGraalJs) { case 'max': return 'Return the maximum of both inputs' } }) + this.setOnChange(function (changeEvent) { + if (changeEvent.type === 'move') { + const typeInfo = computeMinMaxOutputType(this, false) + this.setOutput(true, typeInfo.leadType) + } + }) this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-math.html#minmax') this.setOutput(true, null) } } - javascriptGenerator['oh_math_minmax'] = function (block) { + function computeMinMaxOutputType (block, throwError) { const operand = block.getFieldValue('OP') - const math_number_input1 = javascriptGenerator.valueToCode(block, 'NUM1', javascriptGenerator.ORDER_FUNCTION_CALL) - const math_number_input2 = javascriptGenerator.valueToCode(block, 'NUM2', javascriptGenerator.ORDER_FUNCTION_CALL) + let math_number_input1 + let math_number_input2 + try { // may throw an exception on workspace startup in unitialized state but we then we can ignore + math_number_input1 = javascriptGenerator.valueToCode(block, 'NUM1', javascriptGenerator.ORDER_FUNCTION_CALL) + math_number_input2 = javascriptGenerator.valueToCode(block, 'NUM2', javascriptGenerator.ORDER_FUNCTION_CALL) + } catch (e) {} /* When dealing with variables, Blockly does not provide type information (type is ""). In this case, we fall back to checking whether the actual input contains "Quantity" or is a number. */ - const inputType1 = blockGetCheckedInputType(block, 'NUM1') || getVariableType(math_number_input1) - const inputType2 = blockGetCheckedInputType(block, 'NUM2') || getVariableType(math_number_input2) + let inputType1 + let inputType2 + try { // may throw an exception on workspace startup in unitialized state but we then we can ignore + inputType1 = blockGetCheckedInputType(block, 'NUM1') || getVariableType(math_number_input1) + inputType2 = blockGetCheckedInputType(block, 'NUM2') || getVariableType(math_number_input2) + } catch (e) {} /* If exactly one of the two inputs is a variable, assume it has the same type as the other input. @@ -291,12 +305,16 @@ export default function (f7, isGraalJs) { /* If both inputs are not the same type and none of them is a variable, throw an Error on code generation. */ - if (inputType1 !== inputType2 && !containsOneVar) { + if (throwError && inputType1 !== inputType2 && !containsOneVar) { throw new Error(`Both operand types need to be equal for ${operand.toUpperCase()}-block (${math_number_input1} -> ${inputType1}, ${math_number_input2} -> ${inputType2})`) } const leadType = inputType1 || inputType1 + return { leadType, math_number_input1, math_number_input2, operand } + } + javascriptGenerator['oh_math_minmax'] = function (block) { + const { leadType, math_number_input1, math_number_input2, operand } = computeMinMaxOutputType(block, true) let code = '' switch (leadType) { From fa311d546e25bac097621d97036f8c5cb4e13047 Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Sun, 8 Oct 2023 14:50:43 +0200 Subject: [PATCH 7/7] Minor improvements & fixes Signed-off-by: Florian Hotze --- .../assets/definitions/blockly/blocks-math.js | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js index a9e7f98b46..d0bd926ed2 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-math.js @@ -228,7 +228,7 @@ export default function (f7, isGraalJs) { method = `Math.exp(${math_number})` break case 'POW10': - method = `Math.pow(10,${math_number})` + method = `Math.pow(10, ${math_number})` break } @@ -266,7 +266,7 @@ export default function (f7, isGraalJs) { }) this.setOnChange(function (changeEvent) { if (changeEvent.type === 'move') { - const typeInfo = computeMinMaxOutputType(this, false) + const typeInfo = computeMinMaxOutputType(this) this.setOutput(true, typeInfo.leadType) } }) @@ -275,12 +275,12 @@ export default function (f7, isGraalJs) { } } - function computeMinMaxOutputType (block, throwError) { + function computeMinMaxOutputType (block, throwError = false) { const operand = block.getFieldValue('OP') let math_number_input1 let math_number_input2 - try { // may throw an exception on workspace startup in unitialized state but we then we can ignore + try { // may throw an exception on workspace startup in uninitialized state but in this case we can ignore math_number_input1 = javascriptGenerator.valueToCode(block, 'NUM1', javascriptGenerator.ORDER_FUNCTION_CALL) math_number_input2 = javascriptGenerator.valueToCode(block, 'NUM2', javascriptGenerator.ORDER_FUNCTION_CALL) } catch (e) {} @@ -291,7 +291,7 @@ export default function (f7, isGraalJs) { */ let inputType1 let inputType2 - try { // may throw an exception on workspace startup in unitialized state but we then we can ignore + try { // may throw an exception on workspace startup in uninitialized state but in this case we can ignore inputType1 = blockGetCheckedInputType(block, 'NUM1') || getVariableType(math_number_input1) inputType2 = blockGetCheckedInputType(block, 'NUM2') || getVariableType(math_number_input2) } catch (e) {} @@ -309,7 +309,7 @@ export default function (f7, isGraalJs) { throw new Error(`Both operand types need to be equal for ${operand.toUpperCase()}-block (${math_number_input1} -> ${inputType1}, ${math_number_input2} -> ${inputType2})`) } - const leadType = inputType1 || inputType1 + const leadType = inputType1 || inputType2 || 'Number' return { leadType, math_number_input1, math_number_input2, operand } } @@ -331,12 +331,8 @@ export default function (f7, isGraalJs) { } /* - * let's deal with variables and try to do our best - * if the type is either Number or Quantity, then we don't mind - * only if the type is empty then we try to detect the type - * if the content of the block contains the word "Quantity", then type is oh_quantity - * if the content of the block otherwise contains a number, then the type is Number - */ + * As Blockly does not provide type information for variables, try to determine it based on the content of the block. + */ function getVariableType (math_number_input) { if (math_number_input.includes('Quantity')) return 'oh_quantity' if (!isNaN(math_number_input)) return 'Number'