Skip to content

Commit

Permalink
Merge f975a31 into fa37199
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-hoehn authored May 7, 2023
2 parents fa37199 + f975a31 commit a0dfd36
Show file tree
Hide file tree
Showing 5 changed files with 544 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,32 +144,56 @@ export default function (f7, isGraalJs) {
*/
Blockly.Blocks['oh_getitem_attribute'] = {
init: function () {
let thisBlock = this
let dropdown = new Blockly.FieldDropdown(
[['name', 'Name'], ['label', 'Label'], ['state', 'State'], ['category', 'Category'], ['tags', 'Tags'], ['groups', 'GroupNames'], ['type', 'Type']],
const block = this
const choices = [['name', 'Name'], ['label', 'Label'], ['state', 'State'], ['category', 'Category'], ['tags', 'Tags'], ['groups', 'GroupNames'], ['type', 'Type']]
if (isGraalJs) {
choices.splice(3, 0, ['numeric state', 'NumericState'])
choices.splice(4, 0, ['quantity state', 'QuantityState'])
}
const dropdown = new Blockly.FieldDropdown(
choices,
function (newMode) {
thisBlock.updateType_(newMode)
block._updateType(newMode)
})
this.appendValueInput('item')
.setCheck('oh_itemtype')
.appendField('get ')
.appendField(dropdown, 'attributeName')
.appendField('of item')
this.setInputsInline(false)

this.setOutput(true, 'String')
this.setColour(0)
this.setTooltip('Retrieve a specific attribute from the item. Note that groups and tags return a list and should be used with the loops-block \'for each item ... in list\'. ')
this.setTooltip(function () {
const attributeName = block.getFieldValue('attributeName')
const TIP = {
'Name': 'name of the Item (string)',
'Label': 'label of the Item (string)',
'State': 'state of the Item (string)',
'Category': 'category of the Item (string)',
'Tags': 'tags of the Item (list of strings -> should be used with the loops-block \'for each item ... in list\')',
'GroupNames': 'groups of the Item (list of strings -> should be used with the loops-block \'for each item ... in list\')',
'Type': 'type of the Item (string)',
'NumericState': 'numeric state of the Item (number)',
'QuantityState': 'Unit of Measurement / quantity state of Item (Quantity)'
}
return TIP[attributeName]
})
this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-items-things.html#get-particular-attributes-of-an-item')
},
/**
* Modify this block to have the correct output type based on the attribute.
*/
updateType_: function (newAttributeName) {
let attributeName = this.getFieldValue('attributeName')
* Modify this block to have the correct output type based on the attribute.
*/
_updateType: function (newAttributeName) {
if (newAttributeName === 'Tags' || newAttributeName === 'GroupNames') {
this.outputConnection.setCheck('Array')
} else {
} else if (['Name', 'Label', 'State', 'Category', 'Type'].includes(newAttributeName)) {
this.outputConnection.setCheck('String')
} else if (newAttributeName === 'NumericState') {
this.outputConnection.setCheck('Number')
} else if (newAttributeName === 'QuantityState') {
this.outputConnection.setCheck('oh_quantity')
}
},
/**
Expand All @@ -188,7 +212,7 @@ export default function (f7, isGraalJs) {
* @this {Blockly.Block}
*/
domToMutation: function (xmlElement) {
this.updateType_(xmlElement.getAttribute('attributeName'))
this._updateType(xmlElement.getAttribute('attributeName'))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,59 @@

import Blockly from 'blockly'
import { javascriptGenerator } from 'blockly/javascript'
import { blockGetCheckedInputType } from './utils'

const unavailMsg = 'Units of Measurements blocks aren\'t supported in "application/javascript;version=ECMAScript-5.1"'

export default function (f7, isGraalJs) {
Blockly.Blocks['oh_quantity_ext'] = {
init: function () {
this.appendDummyInput()
.appendField('Qty ')
this.appendValueInput('value')
.setCheck(['String', 'oh_itemtype', 'oh_item'])
this.appendValueInput('unit')
.setCheck('String')
this.setColour(58)
this.setInputsInline(true)
this.setTooltip('Block that wraps Measurements in a Quantity block.\nA Quantity is a Number plus a Unit (of Measurement). \nMake sure you use the right units like 5.75 m, 1 N*m, 1 m/s, 1 m^2/s^2, 1 m^2/s^-2 ... ')
this.setHelpUrl('https://www.openhab.org/docs/concepts/units-of-measurement.html')
this.setOutput(true, ['oh_quantity', 'String'])
}
}

javascriptGenerator['oh_quantity_ext'] = function (block) {
let value = javascriptGenerator.valueToCode(block, 'value', javascriptGenerator.ORDER_NONE)
const unit = javascriptGenerator.valueToCode(block, 'unit', javascriptGenerator.ORDER_NONE)
const inputType = blockGetCheckedInputType(block, 'value')

let code
switch (inputType) {
case 'String':
code = `Quantity(${value} + ${unit})`
break
case 'oh_itemtype':
code = `(${value}.quantityState !== null) ? ${value}.quantityState.toUnit(${unit}) : Quantity(${value}.numericState + ${unit})`
break
case 'oh_item':
value = `items.getItem(${value})`
code = `(${value}.quantityState !== null) ? ${value}.quantityState.toUnit(${unit}) : Quantity(${value}.numericState + ${unit})`
break
}

if (isGraalJs) {
return [code, 0]
} else {
throw new Error(unavailMsg)
}
}

Blockly.Blocks['oh_quantity'] = {
init: function () {
this.appendDummyInput()
.appendField('Qty ')
this.appendValueInput('quantity')
.setCheck('String')
.setCheck(['String', 'oh_itemtype', 'oh_item'])
this.setColour(58)
this.setInputsInline(true)
this.setTooltip('Block that wraps Measurements in a Quantity block.\nA Quantity is a Number plus a Unit (of Measurement). \nMake sure you use the right units like 5.75 m, 1 N*m, 1 m/s, 1 m^2/s^2, 1 m^2/s^-2 ... ')
Expand All @@ -22,20 +67,21 @@ export default function (f7, isGraalJs) {
}

javascriptGenerator['oh_quantity'] = function (block) {
const quantity = javascriptGenerator.valueToCode(block, 'quantity', javascriptGenerator.ORDER_NONE)
if (isGraalJs) {
return [`Quantity(${quantity})`, 0]
return [generateQuantityCode(block, 'quantity'), 0]
} else {
throw new Error(unavailMsg)
}
}

Blockly.Blocks['oh_quantity_arithmetic'] = {
init: function () {
this.appendDummyInput()
.appendField('Qty ')
this.appendValueInput('first')
.setCheck('oh_quantity')
.setCheck(['oh_quantity', 'oh_itemtype', 'oh_item'])
this.appendValueInput('second')
.setCheck(['oh_quantity', 'Number'])
.setCheck(['oh_quantity', 'Number', 'oh_itemtype', 'oh_item'])
.appendField(new Blockly.FieldDropdown([
['+', 'add'], ['-', 'subtract'],
['*', 'multiply'], ['/', 'divide']
Expand All @@ -44,16 +90,20 @@ export default function (f7, isGraalJs) {
this.setInputsInline(true)
this.setOutput(true, 'oh_quantity')
this.setColour('%{BKY_MATH_HUE}')
this.setTooltip('Allows computation with Quantity blocks.\nA Quantity is a Number plus a Unit (of Measurement). \nMake sure you use the right units like 5.75 m, 1 N*m, 1 m/s, 1 m^2/s^2, 1 m^2/s^-2 ... ')
this.setTooltip('Allows computation with Quantity blocks.\nA Quantity is a Number plus a Unit (of Measurement).\nNumbers must only be used with multiplication and division or it will fail.\nMake sure you use the right units like 5.75 m, 1 N*m, 1 m/s, 1 m^2/s^2, 1 m^2/s^-2 ... ')
this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/')
}
}

javascriptGenerator['oh_quantity_arithmetic'] = function (block) {
if (isGraalJs) {
const first = javascriptGenerator.valueToCode(block, 'first', javascriptGenerator.ORDER_NONE)
const second = javascriptGenerator.valueToCode(block, 'second', javascriptGenerator.ORDER_NONE)
const operand = block.getFieldValue('operand')

const first = generateQuantityCode(block, 'first')
const second = (blockGetCheckedInputType(block, 'second') !== 'Number')
? generateQuantityCode(block, 'second')
: javascriptGenerator.valueToCode(block, 'second', javascriptGenerator.ORDER_NONE)

return [`${first}.${operand}(${second})`, javascriptGenerator.ORDER_NONE]
} else {
throw new Error(unavailMsg)
Expand All @@ -62,10 +112,12 @@ export default function (f7, isGraalJs) {

Blockly.Blocks['oh_quantity_compare'] = {
init: function () {
this.appendDummyInput()
.appendField('Qty ')
this.appendValueInput('first')
.setCheck('oh_quantity')
.setCheck(['oh_quantity', 'oh_itemtype', 'oh_item', 'String'])
this.appendValueInput('second')
.setCheck('oh_quantity')
.setCheck(['oh_quantity', 'oh_itemtype', 'oh_item', 'String'])
.appendField(new Blockly.FieldDropdown([
['=', 'equal'],
// ['\u2260', 'NEQ'], // maybe later by adding a not
Expand All @@ -84,11 +136,12 @@ export default function (f7, isGraalJs) {
}

javascriptGenerator['oh_quantity_compare'] = function (block) {
const itemName = javascriptGenerator.valueToCode(block, 'itemName', javascriptGenerator.ORDER_ATOMIC)
if (isGraalJs) {
const first = javascriptGenerator.valueToCode(block, 'first', javascriptGenerator.ORDER_NONE)
const second = javascriptGenerator.valueToCode(block, 'second', javascriptGenerator.ORDER_NONE)
const operand = block.getFieldValue('operand')

const first = generateQuantityCode(block, 'first')
const second = generateQuantityCode(block, 'second')

return [`${first}.${operand}(${second})`, javascriptGenerator.ORDER_NONE]
} else {
throw new Error(unavailMsg)
Expand Down Expand Up @@ -120,3 +173,33 @@ export default function (f7, isGraalJs) {
}
}
}

/**
* Generates the Quantity code for a given input of a Block.
* Supported input types: `oh_quantity`, `String`, `oh_itemtype`, `oh_item`
*
* @param {Blockly.Block} block
* @param {string} inputName name of the input
* @returns {string} generated Quantity code
*/
function generateQuantityCode (block, inputName) {
const input = javascriptGenerator.valueToCode(block, inputName, javascriptGenerator.ORDER_NONE)
const inputType = blockGetCheckedInputType(block, inputName)

let code = ''
switch (inputType) {
case 'oh_quantity':
code = input
break
case 'String':
code = `Quantity(${input})`
break
case 'oh_itemtype':
code = `${input}.quantityState`
break
case 'oh_item':
code = `items.getItem(${input}).quantityState`
break
}
return code
}
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,18 @@
</shadow>
</value>
</block>
<block type="oh_quantity_ext">
<value name="value">
<shadow type="text">
<field name="TEXT">10</field>
</shadow>
</value>
<value name="unit">
<shadow type="text">
<field name="TEXT">W</field>
</shadow>
</value>
</block>
<block type="oh_quantity_arithmetic">
<value name="first">
<shadow type="oh_quantity" />
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit a0dfd36

Please sign in to comment.